2017-05-04 85 views
-1

我试图创建一个属性串,但下划线涵盖了我的文字,而不是显示它背后的:下划线涵盖文字NSAttributedString

enter image description here

是有办法解决这一问题?我正在使用以下代码:

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) 

谢谢!

编辑:

为了让更多的上下文:

我上显示一个UILabel的属性串放在一个文件的.xib:

view.textLabel.attributedText = attributedString 

标签有以下字体: 系统粗体32.0

我在iPhone 6 - iOS 10.3模拟器上运行代码。

编辑2:

我应该提到的是,标签可能在某些时候,包含文本的多行。这就是为什么numberOfLines设置为0.

编辑3: 如果有人遇到这个问题 - 好像在iOS 9和10以及UILabel和UITextView上绘制下划线有很大的区别。我最终不得不通过继承NSLayoutManager来自己绘制下划线。

+1

无法重现问题。在我的机器上,下划线很好地与文本分开,并且不与“y”的下行相交。 https://i.stack.imgur.com/uXs4R.png请显示更多的代码,使其具有可重现性。你如何显示这个属性字符串?你使用什么字体?等等。 – matt

+0

同样在这里,我也无法在我的机器上复制您的问题。它与文本很好地分开显示。 @GrzegorzAperliński – iPeter

+0

(另外我可能会提到你的代码没有在我的机器上编译,需要明确声明'attributes'属于类型'[String:Any]'。) – matt

回答

2

是的,存在如您所描述的问题。当你使用多行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

所以对这种行为的原因当然是bugNSAttributedString 。由于它在雷达提到有一个解决方法

您应该将此属性添加到您的NSAttributedString

和魔术会发生。

+0

感谢!我实际上已经使用NSLayoutManager的子类实现了自定义绘图。希望这个问题将来会得到解决。 –

2

在我的机器,显示一个黑色背景执行的UILabel你的属性串,它使一个相当不错的水准的展示:

enter image description here

红色粗底线是很好的从文本分离,是中断以允许“y”的下行通过它。

注意您不能将UILabel的font(在Interface Builder中设置)与其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 

(你会发现,我删除了你的段落行间距的规定,有的只是一条线,所以这一规定增加了什么不过,我得到了相同的结果甚至。如果我恢复它。)

+0

谢谢!实际上,我注意到在代码和IB中设置的字体权重之间几乎没有什么区别,至少在渲染时。我终于发现了问题的根源(并编辑了原始条目) - 如果将行数设置为0,则会出现问题。对不起,我应该提到我正在更改此内容,但并不认为它是相关的... –

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) 
+2

谢谢!我考虑过这样做,但可能有不止一行文字,所以这不会为我剪下来。 –

2

所以这是我对这个问题的解决方案。 我认为这是“更清洁”,更容易。 如果您不明白,请通知我:)

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 
    } 
} 
+1

只要只有一行文字,此解决方案就可以。 –

+1

嗨@GrzegorzAperliński,你说得对。 我这样做只是为了一行 – ironRoei