下划线覆盖 NSAttributedString 中的文本
Underline covers text in NSAttributedString
我正在尝试创建一个属性字符串,但下划线覆盖了我的文本而不是出现在它后面:
有办法解决这个问题吗?我正在使用以下代码:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10.0
let attributes = [NSForegroundColorAttributeName: UIColor.white,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleThick.rawValue,
NSUnderlineColorAttributeName: UIColor.red,
NSParagraphStyleAttributeName: paragraphStyle]
let attributedString = NSAttributedString(string: "Story", attributes: attributes)
谢谢!
编辑:
提供更多背景信息:
我在 .xib 文件中的 UILabel 上显示属性字符串:
view.textLabel.attributedText = attributedString
标签的字体如下:
系统粗体 32.0
我是 运行 iPhone 6 - iOS 10.3 模拟器上的代码。
编辑 2:
我应该提到标签在某些时候可能包含不止一行文本。这就是将 numberOfLines 设置为 0 的原因。
编辑 3:
如果有人遇到这个问题 - iOS 9 与 10 以及 UILabel 与 UITextView 的下划线绘制方式似乎有很大差异。我最终不得不通过子类化 NSLayoutManager 自己绘制下划线。
在我的机器上,在黑色背景的 UILabel 中显示您的属性字符串,显示效果非常漂亮:
红色粗下划线与文本很好地分开,并且被打断以允许 "y" 的下行部分穿过它。
注意 您不能将 UILabel(在 Interface Builder 中设置)的 font
与其 attributedText
结合使用。您必须在 attributedText
中设置 整个 标签的文本格式。所以,我的代码如下所示:
let attributes : [String:Any] = [NSForegroundColorAttributeName: UIColor.white,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleThick.rawValue,
NSUnderlineColorAttributeName: UIColor.red,
NSFontAttributeName: UIFont.boldSystemFont(ofSize: 32)]
let attributedString = NSAttributedString(string: "Story", attributes: attributes)
lab.backgroundColor = .black
lab.attributedText = attributedString
(你会发现我去掉了你对段落行距的规定,因为只有一行,所以这个规定什么也没有增加。但是,我恢复也是一样的结果。)
除了使用 NSAttributedString,您还可以使用 x space 在标签下方绘制边框。
let space:CGFloat = 10
let border = CALayer()
border.backgroundColor = UIColor.red.cgColor
border.frame = CGRect(x: 0, y: (label?.frame.size.height)! + space, width: (label?.frame.size.width)!, height: 1)
label?.layer.addSublayer(border)
是的,确实存在您描述的问题。它在您使用多行 UILabel
时显示,因此不仅将 numberOfLines
设置为 0,而且在其中键入多于 1 行。
例子
let selectedStringAttributes: [String: Any]
= [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 28),
NSForegroundColorAttributeName: UIColor.green,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue,
NSUnderlineColorAttributeName: UIColor.green]
let label = UILabel(frame: CGRect(x: 100, y: 100, width: 500, height: 100))
label.numberOfLines = 0
label.attributedText = NSAttributedString(string: "String to test underline", attributes: selectedStringAttributes)
一切都会很好看。
但是如果你想使用这样的文字:
label.attributedText = NSAttributedString(string: "String to\ntest underline", attributes: selectedStringAttributes)
或者标签的宽度太短,比:
Not so good
所以出现这种行为的原因当然是bug in NSAttributedString
。正如雷达中提到的那样,有一个 解决方法
您应该将此属性添加到您的 NSAttributedString
NSBaselineOffsetAttributeName: 0
奇迹将会发生。
所以这是我对这个问题的解决方案。
我认为它 "cleaner" 并且更容易。
Post不懂就说我:)
class BottomLineTextField: UITextField {
var bottomBorder = UIView()
override func awakeFromNib() {
super.awakeFromNib()
setBottomBorder()
}
func setBottomBorder() {
self.translatesAutoresizingMaskIntoConstraints = false
bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
hasError = false
bottomBorder.translatesAutoresizingMaskIntoConstraints = false
addSubview(bottomBorder)
bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set underline height
}
}
我正在尝试创建一个属性字符串,但下划线覆盖了我的文本而不是出现在它后面:
有办法解决这个问题吗?我正在使用以下代码:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 10.0
let attributes = [NSForegroundColorAttributeName: UIColor.white,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleThick.rawValue,
NSUnderlineColorAttributeName: UIColor.red,
NSParagraphStyleAttributeName: paragraphStyle]
let attributedString = NSAttributedString(string: "Story", attributes: attributes)
谢谢!
编辑:
提供更多背景信息:
我在 .xib 文件中的 UILabel 上显示属性字符串:
view.textLabel.attributedText = attributedString
标签的字体如下: 系统粗体 32.0
我是 运行 iPhone 6 - iOS 10.3 模拟器上的代码。
编辑 2:
我应该提到标签在某些时候可能包含不止一行文本。这就是将 numberOfLines 设置为 0 的原因。
编辑 3: 如果有人遇到这个问题 - iOS 9 与 10 以及 UILabel 与 UITextView 的下划线绘制方式似乎有很大差异。我最终不得不通过子类化 NSLayoutManager 自己绘制下划线。
在我的机器上,在黑色背景的 UILabel 中显示您的属性字符串,显示效果非常漂亮:
红色粗下划线与文本很好地分开,并且被打断以允许 "y" 的下行部分穿过它。
注意 您不能将 UILabel(在 Interface Builder 中设置)的 font
与其 attributedText
结合使用。您必须在 attributedText
中设置 整个 标签的文本格式。所以,我的代码如下所示:
let attributes : [String:Any] = [NSForegroundColorAttributeName: UIColor.white,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleThick.rawValue,
NSUnderlineColorAttributeName: UIColor.red,
NSFontAttributeName: UIFont.boldSystemFont(ofSize: 32)]
let attributedString = NSAttributedString(string: "Story", attributes: attributes)
lab.backgroundColor = .black
lab.attributedText = attributedString
(你会发现我去掉了你对段落行距的规定,因为只有一行,所以这个规定什么也没有增加。但是,我恢复也是一样的结果。)
除了使用 NSAttributedString,您还可以使用 x space 在标签下方绘制边框。
let space:CGFloat = 10
let border = CALayer()
border.backgroundColor = UIColor.red.cgColor
border.frame = CGRect(x: 0, y: (label?.frame.size.height)! + space, width: (label?.frame.size.width)!, height: 1)
label?.layer.addSublayer(border)
是的,确实存在您描述的问题。它在您使用多行 UILabel
时显示,因此不仅将 numberOfLines
设置为 0,而且在其中键入多于 1 行。
例子
let selectedStringAttributes: [String: Any]
= [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 28),
NSForegroundColorAttributeName: UIColor.green,
NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue,
NSUnderlineColorAttributeName: UIColor.green]
let label = UILabel(frame: CGRect(x: 100, y: 100, width: 500, height: 100))
label.numberOfLines = 0
label.attributedText = NSAttributedString(string: "String to test underline", attributes: selectedStringAttributes)
一切都会很好看。
但是如果你想使用这样的文字:
label.attributedText = NSAttributedString(string: "String to\ntest underline", attributes: selectedStringAttributes)
或者标签的宽度太短,比:
Not so good
所以出现这种行为的原因当然是bug in NSAttributedString
。正如雷达中提到的那样,有一个 解决方法
您应该将此属性添加到您的 NSAttributedString
NSBaselineOffsetAttributeName: 0
奇迹将会发生。
所以这是我对这个问题的解决方案。 我认为它 "cleaner" 并且更容易。 Post不懂就说我:)
class BottomLineTextField: UITextField {
var bottomBorder = UIView()
override func awakeFromNib() {
super.awakeFromNib()
setBottomBorder()
}
func setBottomBorder() {
self.translatesAutoresizingMaskIntoConstraints = false
bottomBorder = UIView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
hasError = false
bottomBorder.translatesAutoresizingMaskIntoConstraints = false
addSubview(bottomBorder)
bottomBorder.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
bottomBorder.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
bottomBorder.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
bottomBorder.heightAnchor.constraint(equalToConstant: 1).isActive = true // Set underline height
}
}