반응형
결과물 이미지부터 볼게요
SwiftUI로 이런 테두리가 있는 Text를 만들어볼거에요!
iOS 17.0기준으로 아직 SwiftUI 모디파이어라던가 뷰 타입에서 Outline에 색을 칠할 수 있는 방법은 따로없어서
커스텀으로 만들어줬어요
메커니즘은 텍스트 2개를 중첩을해서 뒷텍스트는 테두리처럼, 앞에꺼는 폰트색처럼 사용하려고해요
만약 SwiftUI의 Text를 2개를 중첩한다면 좀더 복잡하고 계산할게 많아져요
또한
SwiftUI에서 사용가능한 AttributedString는 테두리가 먹히질 않아서 실패했어요
따라서
UIKit에 있는 UILabel을 사용할거에요
NSAttributedString을 이용해서 테두리를 적용시켜줄건데
이때 속성으로 strokeColor와 foregroundColor 둘다 적용할 수 가 없어요
(foregroundColor를 적용하나 strokeColor를 적용하나 똑같이 폰트색이 적용됩니다
하지만 명시적으로 테두리색 느낌을 주기위해 stroke를 사용했습니다)
해보시면 알겠지만 둘중 하나만 적용됩니다!
테두리가될 뷰를 먼저 만들어봅시다!
// SwiftUI로는 AttributeString적용시 text stroke속성 적용불가능
struct StrokeText: UIViewRepresentable {
let text: String
let font: UIFont
let strokeColor: UIColor
let strokeWidth: CGFloat
func makeUIView(context: Context) -> UILabel {
let label: UILabel = UILabel()
let attribute: [NSAttributedString.Key: Any] = [
.strokeColor: strokeColor,
.strokeWidth: strokeWidth,
.font: font
]
label.attributedText = NSAttributedString(string: text, attributes: attribute)
label.sizeToFit()
label.textAlignment = .center
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
let attribute: [NSAttributedString.Key: Any] = [
.strokeColor: strokeColor,
.strokeWidth: strokeWidth,
.font: font
]
uiView.attributedText = NSAttributedString(string: text, attributes: attribute)
uiView.textAlignment = .center
uiView.sizeToFit()
}
}
속성에 필요한것들을 넣어주고...
그다음으로는 위에서만든 테두리뷰에 SwiftUI의 Text를 위에 얹어서 완성시켜볼게요
struct StrokeTextView: View {
let text: String
let textColor: Color
let font: PretendardFont
let fontSize: CGFloat
let strokeColor: Color
let strokeWidth: CGFloat
private var storkeUIColor: UIColor { UIColor(strokeColor) }
init(
text: String,
textColor: Color,
font: PretendardFont,
fontSize: CGFloat,
strokeColor: Color,
strokeWidth: CGFloat = 15
) {
self.text = text
self.textColor = textColor
self.font = font
self.fontSize = fontSize
self.strokeColor = strokeColor
self.strokeWidth = strokeWidth
}
var body: some View {
StrokeText(
text: text,
font: UIFont(name: font.rawValue, size: fontSize)!,
strokeColor: storkeUIColor,
strokeWidth: strokeWidth
)
.overlay {
Text(text)
.font(.custom(font.rawValue, size: fontSize))
.foregroundStyle(textColor)
}
}
}
사용할땐 만들어두면
이렇게 쉽게 적용가능합니다!
#Preview {
StrokeTextView(
text: "NSiOS",
textColor: .purple,
font: .bold,
fontSize: 50,
strokeColor: .black,
strokeWidth: 12
)
}
이쁘네요!
반응형