iOS: 围绕文本 UILabel 绘制边框
iOS: Draw border around text UILabel
我想像这样在 UILabel
的文本周围画一个轮廓:
我尝试使用属性文本,但没有用于渲染文本周围边框的属性。只有下划线可用。我还尝试使用属性文本渲染 html 但这也没有帮助:
let htmlLabelText = String(format: "<html><body><span style='color:blue; border: 1.5px solid #55DF49; border-radius: 50px;'>%@</span></body></html>", labelText)
var attributedString = NSMutableAttributedString()
guard let stringData = data(using: .unicode) else { return NSMutableAttributedString() }
do {
attributedString = try NSMutableAttributedString(
data: stringData,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil
)
} catch {}
我检查了其他 post,但其中 none 有帮助。
答案在这里。
label1.layer.borderColor = [UIColor greenColor].CGColor;
label1.layer.borderWidth =1.0
或
label2.layer.borderColor = [UIColor blueColor].CGColor;
label1.layer.borderWidth =5.0
或
label3.layer.borderWidth = 2.0;
label3.layer.cornerRadius = 8;
尝试这些不同的可能性。
UILabel 的问题很难解决,因为您无法直接访问 NSLayoutManager,这是我解决方案的关键。
我创建了 IBDesignable UILabel 子类 LineHighlightedLabel,它可以完成这项工作。视觉效果与您提供的图像不太一样,但您可以看到。
重要的部分是将文本设置为 UILabel 作为 NSAttributedString,而不仅仅是纯文本。
@IBDesignable
public class LineHighlightedLabel: UILabel {
public override func draw(_ rect: CGRect) {
let layoutManager = NSLayoutManager()
let textStorage = NSTextStorage.init(attributedString: attributedText!)
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer.init(size: bounds.size)
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = numberOfLines
textContainer.lineBreakMode = lineBreakMode
layoutManager.addTextContainer(textContainer)
layoutManager.enumerateLineFragments(forGlyphRange: NSMakeRange(0, textStorage.length)) { (rect, usedRect, textContainer, glyphRange, bool) in
let lineRect = CGRect(x: usedRect.origin.x, y: usedRect.origin.y + 1, width: usedRect.size.width, height: usedRect.size.height - 2)
UIColor.green.setStroke()
let lineRectPath = UIBezierPath(roundedRect: lineRect, cornerRadius: 5)
lineRectPath.lineWidth = 0.5
lineRectPath.stroke()
}
super.drawText(in: rect)
}
public override func layoutSubviews() {
super.layoutSubviews()
setNeedsDisplay()
}
}
LineHighlightedLabel 在界面生成器中提供了很好的预览,您可以轻松地使用值。
@shota 的回答也有效。
Here 正是我在不使用 NSLayoutManager 的情况下通过继承 UILabel 来解决问题的方法。我从 Whosebug 的某处复制了从文本中获取行的代码,尽管使用 LayoutManager.enumerateLineFragments 是更好的选择。还需要 hack 来呈现 UILabel 的文本,在开始和结束处有两个空格。这是最终结果的屏幕截图:
我想像这样在 UILabel
的文本周围画一个轮廓:
我尝试使用属性文本,但没有用于渲染文本周围边框的属性。只有下划线可用。我还尝试使用属性文本渲染 html 但这也没有帮助:
let htmlLabelText = String(format: "<html><body><span style='color:blue; border: 1.5px solid #55DF49; border-radius: 50px;'>%@</span></body></html>", labelText)
var attributedString = NSMutableAttributedString()
guard let stringData = data(using: .unicode) else { return NSMutableAttributedString() }
do {
attributedString = try NSMutableAttributedString(
data: stringData,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil
)
} catch {}
我检查了其他 post,但其中 none 有帮助。
答案在这里。
label1.layer.borderColor = [UIColor greenColor].CGColor;
label1.layer.borderWidth =1.0
或
label2.layer.borderColor = [UIColor blueColor].CGColor;
label1.layer.borderWidth =5.0
或
label3.layer.borderWidth = 2.0;
label3.layer.cornerRadius = 8;
尝试这些不同的可能性。
UILabel 的问题很难解决,因为您无法直接访问 NSLayoutManager,这是我解决方案的关键。
我创建了 IBDesignable UILabel 子类 LineHighlightedLabel,它可以完成这项工作。视觉效果与您提供的图像不太一样,但您可以看到。
重要的部分是将文本设置为 UILabel 作为 NSAttributedString,而不仅仅是纯文本。
@IBDesignable
public class LineHighlightedLabel: UILabel {
public override func draw(_ rect: CGRect) {
let layoutManager = NSLayoutManager()
let textStorage = NSTextStorage.init(attributedString: attributedText!)
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer.init(size: bounds.size)
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = numberOfLines
textContainer.lineBreakMode = lineBreakMode
layoutManager.addTextContainer(textContainer)
layoutManager.enumerateLineFragments(forGlyphRange: NSMakeRange(0, textStorage.length)) { (rect, usedRect, textContainer, glyphRange, bool) in
let lineRect = CGRect(x: usedRect.origin.x, y: usedRect.origin.y + 1, width: usedRect.size.width, height: usedRect.size.height - 2)
UIColor.green.setStroke()
let lineRectPath = UIBezierPath(roundedRect: lineRect, cornerRadius: 5)
lineRectPath.lineWidth = 0.5
lineRectPath.stroke()
}
super.drawText(in: rect)
}
public override func layoutSubviews() {
super.layoutSubviews()
setNeedsDisplay()
}
}
LineHighlightedLabel 在界面生成器中提供了很好的预览,您可以轻松地使用值。
@shota 的回答也有效。
Here 正是我在不使用 NSLayoutManager 的情况下通过继承 UILabel 来解决问题的方法。我从 Whosebug 的某处复制了从文本中获取行的代码,尽管使用 LayoutManager.enumerateLineFragments 是更好的选择。还需要 hack 来呈现 UILabel 的文本,在开始和结束处有两个空格。这是最终结果的屏幕截图: