1

I am trying to present the user with a TableView, within each cell of the table view there is an image and a textView, I am providing the textView.text with a single string for each cell, however within each string, I'd like that there could be multiple fonts. For example, one part of the string will have a size of 20 and bold and the rest will have a size of 14 and Regular. You can see what I have in my app in the following image

enter image description here

As you can see, I tried to edit the "How do you trade stocks?" part of the string with NSMutableAtributtedString, however the output was the settings of it rather than the string with the selected properties. The code I used is the following:

let title1 = "How do you trade stocks?"

let atributtedTitle1 = NSMutableAttributedString(string: title1)

atributtedTitle1.addAttributes([NSAttributedStringKey.foregroundColor: UIColor.black, NSAttributedStringKey.font: UIFont(name: "AvenirNext-Bold", size: 20)!], range: getRangeOfSubString(subString: title1, fromString: title1))

var textViews:[String] = ["\(atributtedTitle1)The stock market is one of the best ways you can build up wealth. The stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealth. The stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealth. The stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealth. The stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealth. The stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealthThe stock market is one of the best ways you can build up wealth"]

Loading the textView text usually as it's done in a tableView with

cell.descriptionTextView.text = textViews[indexPath.row]

And the function I used to calculate the range in NSMutableAtributtedString is as follows:

func getRangeOfSubString(subString: String, fromString: String) -> NSRange {
    let sampleLinkRange = fromString.range(of: subString)!
    let startPos = fromString.distance(from: fromString.startIndex, to: sampleLinkRange.lowerBound)
    let endPos = fromString.distance(from: fromString.startIndex, to: sampleLinkRange.upperBound)
    let linkRange = NSMakeRange(startPos, endPos - startPos)
    return linkRange
}

How could I have multiple fonts and sizes in a single string so I can provide it to a single textView?

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
Francisco Ruiz
  • 209
  • 3
  • 12
  • Possible duplicate of [How do you use NSAttributedString?](https://stackoverflow.com/questions/3482346/how-do-you-use-nsattributedstring) – Tj3n Apr 20 '18 at 03:03
  • It's in the second and third lines that I posted, that's the only time I use NSMutableAttributedString – Francisco Ruiz Apr 20 '18 at 03:10

1 Answers1

4

As a direct answer for your question:

Is it possible to have multiple fonts and sizes in a single string in a TextView?

Yes there is. Setup aNSMutableAttributedString as it should, would get the desired result. For instance, calling the following method:

func setupTextViewAttributedString() {
    let myString = "The quick brown fox jumps over the lazy dog"
    let myAttributedString = NSMutableAttributedString(string: myString)
    myAttributedString.addAttribute(
        .font, value: UIFont.boldSystemFont(ofSize: 20),
        range: NSRange(location:0,length:4))

    myAttributedString.addAttributes([.foregroundColor : UIColor.red,
                                      .font: UIFont.boldSystemFont(ofSize: 20)],
                                     range: NSRange(location:0,length:19))

    myAttributedString.addAttributes([.foregroundColor : UIColor.blue,
                                      .font: UIFont.systemFont(ofSize: 14)],
                                     range: NSRange(location:20,length:4))

    myAttributedString.addAttributes([.foregroundColor : UIColor.green,
                                      .font: UIFont.systemFont(ofSize: 16)],
                                     range: NSRange(location:25,length:myString.count - 25))

    textView.attributedText = myAttributedString
}

would give the following output:

enter image description here

By setting attributes -with a given range- (using addAttributes(_:range:)), you even set more than one attribute at a time, as shown above, I setted the font and the color of the desired range of text.

Furthermore:

If you are aiming to evaluate HTML, you could do it like this:

func evaluateHTMLString() {
    let htmlString = """
                        <font color=\"red\">The quick brown fox </font>
                        <font color=\"blue\">jumps </font>
                        <font color=\"green\">over the lazy dog</font>
                     """
    let attributedString = try! NSAttributedString(data: htmlString.data(using: .utf8)!,
                                                      options: [.documentType: NSAttributedString.DocumentType.html],
                                                      documentAttributes: nil)

    textView.attributedText = attributedString
}

Output:

enter image description here

Ahmad F
  • 30,560
  • 17
  • 97
  • 143