Home > Back-end >  How to show numbers for each paragraph in Swift label
How to show numbers for each paragraph in Swift label

Time:07-13

I am getting string from server is like below, Due to privacy policy I have added some static text.

"\n1. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen . \n2. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen \n3. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen…\n"

The above text I have to show like below format.

1. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen .

2. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen

3. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen…

Also the index numbers should have different color to show in label.

Any suggestions?

CodePudding user response:

First, the \n character is a newline character, so it will be handled by the UILabel for you. So, all you need to do is to set the foregroundColor for matches of the number at the start of each line. E.g.

let string = "\n1. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen . \n2. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen \n3. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen…\n"
let attributedString = NSMutableAttributedString(string: string)

let regex = try! NSRegularExpression(pattern: #"^\d \."#, options: .anchorsMatchLines)
let range = NSRange(location: 0, length: attributedString.length)
regex.enumerateMatches(in: string, range: range) { result, _, _ in
    guard let range = result?.range else { return }
    attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: range)
}

label.numberOfLines = 0
label.attributedText = attributedString

That will yield:

enter image description here

If you want an extra blank line, replace all \n with \n\n:

let string = "\n1. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen . \n2. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen \n3. You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen…\n"
    .trimmingCharacters(in: .whitespacesAndNewlines)
    .replacingOccurrences(of: "\n", with: "\n\n")

Which, if you then repeat the above NSMutableAttributedString logic, yields:

enter image description here


If you want it to look like a real list, with indentation, you would probably have to reformat the text into HTML (which would, itself, be an annoying exercise), then back to a NSAttributedString and format the numbers there:


let string = """
    <style>
    li {
        color: white;
        font-family: Arial, Helvetica, sans-serif;
        font-size: 12pt;
        margin-bottom: 12pt;
    }
    </style>
    <ol>
    <li>You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen .</li>
    <li>You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen</li>
    <li>You are Lorem ipsum doller sit amen Lorem ipsum doller sit amen Lorem ipsum doller sit amen…</li>
    </ol>
    """
guard let data = string.data(using: .utf16) else { return }

let attributedString = try! NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)

let regex = try! NSRegularExpression(pattern: #"^\s*\d \."#, options: .anchorsMatchLines)
let range = NSRange(location: 0, length: attributedString.length)
regex.enumerateMatches(in: attributedString.string, range: range) { result, _, _ in
    guard let range = result?.range else { return }
    attributedString.addAttribute(.foregroundColor, value: UIColor.red, range: range)
}

label.attributedText = attributedString

If you know your CSS, you might be inclined to add a coloring via the <style> for ol:before, but that does not appear to work. (If you’re not up on your CSS and didn’t follow what I said, just ignore it, as it doesn’t work, anyway.)

Anyway, if you go through all of that work, that yields:

enter image description here

  • Related