Search code examples
iosuilabelnsattributedstring

Change paragraph height (not line spacing) in a UILabel


Is it possible to limit the distance between paragraphs that were created using \n\n smaller in UILabels using attributed strings?

So for example, I would like this: enter image description here

To look like this:

enter image description here

Would this involve replace \n\n with something else? Or is there a much simpler solution using NSAttributedString?


Solution

  • One thing I didn't mention in the question, which I had thought was obvious from the example is that the description is not within my control, it is generated by users. Therefore, the carriage return characters are added by them when they are creating the text.

    So the solution I came up with is the following:

    Firstly, I replace any \n\n characters with a single carriage return. This was inspired by amin-negm-awad's answer. \n\n is not a desirable way to generate a paragraph space.

    I am doing this using the following piece of code:

    func sanitize() -> String {
        var output = NSMutableString(string: self)
        var numberOfReplacements = 0
        do {
            let range = NSMakeRange(0, output.length)
            numberOfReplacements = newString.replaceOccurrencesOfString("\n\n", withString: "\n", options: NSStringCompareOptions.CaseInsensitiveSearch, range: range)
        } while (numberOfReplacements > 0)
        return output as String
    }
    

    The next part is to apply a paragraph style with an attributed string. Here is an example function that is fairly flexible:

    func textAttributesWithFont(font: UIFont, andColor color: UIColor,
        lineSpacing: CGFloat = 0,
        maximumLineHeight: CGFloat = 0,
        textAlignment: NSTextAlignment = .Natural) -> [NSObject: AnyObject] {
            var attributes = [NSFontAttributeName : font, NSForegroundColorAttributeName : color]
            var paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = lineSpacing
            paragraphStyle.alignment = textAlignment
            paragraphStyle.maximumLineHeight = maximumLineHeight
            paragraphStyle.paragraphSpacing = 4
            attributes[NSParagraphStyleAttributeName] = paragraphStyle
            return attributes
    }
    

    Finally the label is constructed using the attributes:

    var label1 = UILabel()
    let text1 = "This is a test that is supposed😓😛😠😑  to wrap with some paragaphs\n\nThis is a paragraph"
    label1.attributedText = NSAttributedString(string:sanitizeComment(text1), attributes: attributes)
    label1.numberOfLines = 0