0

I am using attributed string to format a single character string for UITextView that will update whenever a button is clicked or a picker is moved. However, because I use attributedStringLine.append(attributedCharString) the attributedString continues to grow rather than start a new attributed string whenever UITextViewis updated.

The code below demonstrates a simplified version of the problem.

NSMutableAttributedString() operates on the string in myArray. New strings are processed whenever UITextView changes. These are in array1, array2 and array3.

import UIKit

var str = "Hello, playground"

let array1                      = ["7.0", "55.55", "1.0", "9.27"]
let array2                      = ["0", "10", "20", "30", "40"]
let array3                      = ["A", "B", "C", "D", "E", "F"]

var myArray                     = [""]
let attributedStringLine        = NSMutableAttributedString()
let numberOfRawStringCharacters = myArray.count


func appendTextString(i: Int){
    let rangeOfCharString       = (myArray[i] as NSString).range(of: myArray[i])
    let attributedCharString    = NSMutableAttributedString.init(string: myArray[i], attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18.0, weight: UIFontWeightLight)])
    attributedCharString.addAttributes([NSForegroundColorAttributeName : UIColor.blue], range: rangeOfCharString)
    attributedStringLine.append(attributedCharString)
}


func makeText() {
    for i in 0..<myArray.count {
        appendTextString(i: i)
    }
}

var line = attributedStringLine.length

myArray.removeAll()
myArray                         = array1
myArray.count
makeText()
print(attributedStringLine)
line = attributedStringLine.length

myArray.removeAll()
myArray                         = array2
myArray.count
makeText()
attributedStringLine
line = attributedStringLine.length

myArray.removeAll()
myArray                         = array3
myArray.count
makeText()
attributedStringLine
line = attributedStringLine.length

How do I start with an empty attributedString whenever the UITextView changes ?

For NSMutableString, replacing or deleting characters from the range of an existing attributed string seems to be the only alternative available. And I'm pretty sure this is not a duplicate of Value of type 'NSMutableAttributedString' has no member 'removeAll'

Community
  • 1
  • 1
Greg
  • 1,750
  • 2
  • 29
  • 56

1 Answers1

1

Since you declared attributedStringLine with let, you can remove all character from it at the start of makeText.

func makeText() {
    attributedStringLine.deleteCharacters(in: NSMakeRange(0, attributedStringLine.length))
    for i in 0..<myArray.count {
        appendTextString(i: i)
    }
}

Or you change its declaration from let to var and then use attributedStringLine = NSMutableAttributedString() at the start of makeText.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Your first solution worked fine in my Xcode project so from my point of view it will be the accepted answer. It’s worth noting that in Playground attributed strings appear correctly formatted for `array2` and `array3`, but for `array1` the unformatted string appears followed by the attributed formatting script enclosed in curly brackets. On the Simulator these numeric floating point characters display correctly. Thanks. – Greg Feb 22 '17 at 00:03