下划线覆盖 NSAttributedString 中的文本
Posted
技术标签:
【中文标题】下划线覆盖 NSAttributedString 中的文本【英文标题】:Underline covers text in NSAttributedString 【发布时间】:2017-05-04 14:27:35 【问题描述】:我正在尝试创建一个属性字符串,但下划线覆盖了我的文本,而不是出现在它后面:
有没有办法解决这个问题?我正在使用以下代码:
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 自己绘制下划线。
【问题讨论】:
无法重现问题。在我的机器上,下划线很好地与文本分开,并且不与“y”的下降线相交。 i.stack.imgur.com/uXs4R.png 请显示更多您的代码,以使其可重现。你如何显示这个属性字符串?你用的是什么字体?以此类推。 这里也一样,我也无法在我的机器上复制您的问题。它与文本很好地分开。 @Grzegorz Aperliński (另外我可能会提到您的代码没有在我的机器上编译。有必要将attributes
明确声明为[String:Any]
类型。)
在主条目中添加了更多详细信息。
查看我修改后的答案。您不能在 Interface Builder 中设置 font
,但在 attributedText
中设置其他所有内容;您必须在您的attributedString
中包含字体规范in。正如我修改后的答案所示,当你这样做时,一切都很好。
【参考方案1】:
是的,存在您所描述的问题。它在你使用多行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
魔法就会发生。
【讨论】:
谢谢!我实际上已经使用 NSLayoutManager 的子类实现了自定义绘图。希望这个问题能在未来得到解决。【参考方案2】:除了使用 NSAttributedString 之外,您还可以使用它在标签下方用 x 空间绘制边框。
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)
【讨论】:
谢谢!我考虑过这样做,但可能有不止一行文字,所以这对我来说并不合适。【参考方案3】:在我的机器上,以黑色背景的 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
(你会注意到我删除了你对段落行距的规定;只有一行,所以这个规定没有增加任何内容。但是,即使我恢复它,我也会得到相同的结果。)
【讨论】:
谢谢!实际上,我注意到代码中设置的字体粗细和 IB 之间几乎没有区别,至少在渲染方面。我终于找到了问题的根源(并编辑了原始条目)——如果您将行数设置为 0,就会出现问题。对不起,我应该提到我正在更改它,但认为它不相关...【参考方案4】:所以这是我对这个问题的解决方案。 我认为它“更清洁”和更容易。 如果你不明白,请给我留言:)
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
【讨论】:
这个方案只要只有一行文字就可以了。 嗨@GrzegorzAperliński,你说得对。我这样做只是为了一行以上是关于下划线覆盖 NSAttributedString 中的文本的主要内容,如果未能解决你的问题,请参考以下文章
UIButton 上的 iOS NSAttributedString