SwiftUI에서는 attributeText를 iOS15부터 지원한다. 따라서 그 이전 버젼은 UIViewRepresentable을 사용해서 커스텀 하거나, Text() + Text() 형식으로 AttributeText를 만든다. 그 중 두번째 방법을 사용해서 간단한 커스텀 AttributeText를 만들어보자. UIViewRepresentable를 사용해서 커스텀 하려니 스유 개초보라 만들어진 View가 제대로 크기를 못잡고 지 맘대로 크기를 잡더라..
(비효율적인 코드를 작성했을 수도 있음.)
attribute를 사용하는 화면마다 Text() + Text() 하기는 너무 비효율적이니, String의 extension으로 함수를 만들어 전체 String에서 특정 텍스트를 바꿀 수 있도록 해보겠음. 그러기 위해 Attribute 속성을 만들기 위한 Protocol을 선언해주겠음.
protocol StringAttributeProtocol {
var weight: Font.Weight { get }
var size: CGFloat { get }
var color: Color { get }
}
이 프로토콜은 현재 텍스트가 가지고 있는 font와 color를 받는다. 그리고,
public struct BaseAttribute: StringAttributeProtocol {
let weight: Font.Weight
let size: CGFloat
let color: Color
public init(weight: Font.Weight, size: CGFloat, color: Color) {
self.weight = weight
self.size = size
self.color = color
}
}
public struct StringAttribute: StringAttributeProtocol {
let text: String
let weight: Font.Weight
let size: CGFloat
let color: Color
public init(text: String, weight: Font.Weight, size: CGFloat, color: Color) {
self.text = text
self.weight = weight
self.size = size
self.color = color
}
}
실제로 값을 받을 수 있도록 프로토콜을 채택한 구현체를 2개 만들어 줬다, 첫번째는 전체 Text에 대한 정보고, 두번째 구현체는 특정 텍스트에 Attribute를 부여할 정보다.
그럼 준비는 다 되었으니 Text를 만들어줄 String extension 함수를 만들어보자.
extension String {
public func toAttributesText(
base: BaseAttribute,
_ attribute: StringAttribute
) -> Text {
var text = Text("")
let parsingStr = self.components(separatedBy: attribute.text)
parsingStr.enumerated().forEach { index, str in
let appendText = self._makeAttributeText(text: str, attribute: base)
text = text + appendText
if index == (parsingStr.count - 1) { return }
let attributeText = self._makeAttributeText(
text: attribute.text,
attribute: attribute
)
text = text + attributeText
}
return text
}
private func _makeAttributeText(
text: String, attribute: StringAttributeProtocol
) -> Text {
return Text(text)
.font(.system(size: attribute.size, weight: attribute.weight))
.foregroundColor(attribute.color)
}
}
첫번째 파라미터로 전체 텍스트에 대한 정보를 받아주고, 두번째 파라미터로 attribute로 바꿀 텍스트의 정보를 받았다. 그리고, 전체 텍스트에서 특정 텍스트를 기준으로 나눠주고, 잘린 텍스트를 기준으로 _makeAttributeText라는 함수를 통해 전체 String의 Text와 잘린 String의 Text를 만들어 하나씩 붙여준다.
반복문을 돌아 모든 정보가 더해진 Text를 리턴하면 원하는 특정 텍스트에만 폰트, 색상이 변경된다.
'iOS > 학습' 카테고리의 다른 글
[iOS] 푸시, 다이나믹 링크 등으로 실행될 때 디버깅하기 (0) | 2023.08.28 |
---|---|
Error) failed to demangle superclass of ‘…’ from mangled name ‘…’ (3) | 2023.05.03 |
TCA) Store vs ViewStore (0) | 2023.02.13 |
Storyboard 에서 Generic Type 의존성 주입하기 2 (0) | 2022.08.29 |
Custom Horizontal FlowLayout (0) | 2022.06.21 |