Search code examples
iosswiftnsattributedstring

NSAttributedString with multiple alignments


I have a UILabel where I would like to have three texts with three alignments: left, center and right. I found the following solution that works with left and right alignment, but I cannot add the center one:

    text = "Pause\n09:30 - 11:30\nsome center text"
    at = NSMutableAttributedString(string: text)
    p1.alignment = .left
    p2.alignment = .right
    p3.alignment = .center
    p2.paragraphSpacingBefore = -labelPause.font.lineHeight
    at.addAttribute(.paragraphStyle, value: p1, range: NSRange(location: 0, length: 4))
    at.addAttribute(.paragraphStyle, value: p3, range: NSRange(location: 4, length: 6))
    at.addAttribute(.paragraphStyle, value: p2, range: NSRange(location: 6, length: 8))
    labelPause.numberOfLines = 0
    labelPause.attributedText = at

The text that should be in the center just appears in the next line left-aligned. What am I doing wrong?


Solution

  • Some of your NSRanges don't match the character offsets you seem to want to target.

    Try this in a playground, it works for me:

    import UIKit
    import PlaygroundSupport
    
    let text = "Pause\n09:30 - 11:30\nsome centered text"
    let at = NSMutableAttributedString(string: text)
    let label = UILabel(frame: CGRect(x: 0, y: 0, width: 400, height: 60))
    var p1 = NSMutableParagraphStyle()
    var p2 = NSMutableParagraphStyle()
    var p3 = NSMutableParagraphStyle()
    
    p1.alignment = .left
    p2.alignment = .right
    p3.alignment = .center
    p2.paragraphSpacingBefore = -label.font.lineHeight
    p3.paragraphSpacingBefore = -label.font.lineHeight
    
    at.addAttribute(.paragraphStyle, value: p1, range: NSRange(location: 0, length: 5))
    at.addAttribute(.paragraphStyle, value: p3, range: NSRange(location: 20, length: 6))
    at.addAttribute(.paragraphStyle, value: p2, range: NSRange(location: 6, length: 13))
    
    
    label.numberOfLines = 0
    label.attributedText = at
    
    PlaygroundPage.current.liveView = label
    
    

    enter image description here