如何在文本 UILabel 周围实现粗描边边框
How to achieve a thick stroked border around text UILabel
这就是我想要实现的目标:
以下是我尝试过的一些方法:
NSAttributedString
我尝试使用具有以下属性的 NSAttributedString
,但 iOS 14+
中的文本路径似乎存在错误
private var attributes: [NSAttributedString.Key: Any] {
[
.strokeColor : strokeColor,
.strokeWidth : -8,
.foregroundColor : foregroundColor,
.font: UIFont.systemFont(ofSize: 17, weight: .black)
]
}
如果 NSAttributedString
的某些字母没有奇怪的路径问题,我完全可以接受这个结果。
绘制文本覆盖
我也尝试过重写 drawText,但据我所知,我找不到任何方法来改变笔划粗细并让它与下一个字符混合在一起:
override func drawText(in rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
context?.setLineJoin(.round)
context?.setTextDrawingMode(.stroke)
self.textColor = strokeColor
super.drawText(in: rect)
context?.setTextDrawingMode(.fill)
self.textColor = foregroundColor
super.drawText(in: rect)
layer.shadowColor = UIColor.black.cgColor
layer.shadowRadius = 2
layer.shadowOpacity = 0.08
layer.shadowOffset = .init(width: 0, height: 2)
}
使用这个可设计的 class 在故事板上渲染带有笔画的标签。我试过的大多数字体看起来都很糟糕(CGLineJoin.miter
),我发现“PingFang TC”字体最接近所需的输出。尽管 CGLineJoin.round
lineJoin 在大多数字体上看起来都不错。
@IBDesignable
class StrokeLabel: UILabel {
@IBInspectable var strokeSize: CGFloat = 0
@IBInspectable var strokeColor: UIColor = .clear
override func drawText(in rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let textColor = self.textColor
context?.setLineWidth(self.strokeSize)
context?.setLineJoin(CGLineJoin.miter)
context?.setTextDrawingMode(CGTextDrawingMode.stroke)
self.textColor = self.strokeColor
super.drawText(in: rect)
context?.setTextDrawingMode(.fill)
self.textColor = textColor
super.drawText(in: rect)
}
}
输出:(在属性检查器中检查使用的值以供参考)
这就是我想要实现的目标:
以下是我尝试过的一些方法:
NSAttributedString
我尝试使用具有以下属性的 NSAttributedString
,但 iOS 14+
private var attributes: [NSAttributedString.Key: Any] {
[
.strokeColor : strokeColor,
.strokeWidth : -8,
.foregroundColor : foregroundColor,
.font: UIFont.systemFont(ofSize: 17, weight: .black)
]
}
如果 NSAttributedString
的某些字母没有奇怪的路径问题,我完全可以接受这个结果。
绘制文本覆盖
我也尝试过重写 drawText,但据我所知,我找不到任何方法来改变笔划粗细并让它与下一个字符混合在一起:
override func drawText(in rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
context?.setLineJoin(.round)
context?.setTextDrawingMode(.stroke)
self.textColor = strokeColor
super.drawText(in: rect)
context?.setTextDrawingMode(.fill)
self.textColor = foregroundColor
super.drawText(in: rect)
layer.shadowColor = UIColor.black.cgColor
layer.shadowRadius = 2
layer.shadowOpacity = 0.08
layer.shadowOffset = .init(width: 0, height: 2)
}
使用这个可设计的 class 在故事板上渲染带有笔画的标签。我试过的大多数字体看起来都很糟糕(CGLineJoin.miter
),我发现“PingFang TC”字体最接近所需的输出。尽管 CGLineJoin.round
lineJoin 在大多数字体上看起来都不错。
@IBDesignable
class StrokeLabel: UILabel {
@IBInspectable var strokeSize: CGFloat = 0
@IBInspectable var strokeColor: UIColor = .clear
override func drawText(in rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let textColor = self.textColor
context?.setLineWidth(self.strokeSize)
context?.setLineJoin(CGLineJoin.miter)
context?.setTextDrawingMode(CGTextDrawingMode.stroke)
self.textColor = self.strokeColor
super.drawText(in: rect)
context?.setTextDrawingMode(.fill)
self.textColor = textColor
super.drawText(in: rect)
}
}
输出:(在属性检查器中检查使用的值以供参考)