Home > Software design >  Setting textView.attributedtext to an array of NSAttributedString values through UserDefaults swift
Setting textView.attributedtext to an array of NSAttributedString values through UserDefaults swift

Time:05-27

I'm stuck.

I set up an array as follows:

    private var lyricArray : [NSAttributedString] = []

I have a game that has matches and misses. For each match I want the color of the text to be green and red for a miss.

I set the code up as follows:

if isMatch == true {
                secondBody.node?.run(colorTransition(fromColor: .init(customName: .brandWhite), toColor: .init(customName: .brandGreen)))

                for lyric in songLyrics {
                     let red = UIColor.init(customName: .brandGreen)
                     let attributedStringColor = [NSAttributedString.Key.foregroundColor : red]
                     let lyricColor = NSAttributedString(string: lyric!, attributes: attributedStringColor)
                    
                    lyricArray.append(lyricColor)
                    
                    print("Your lyric array looks like this: \(lyricArray)")
                    do {
//if i set the root object to lyricColor it will show it in the resulting text view
                        let data = try NSKeyedArchiver.archivedData(withRootObject: lyricArray, requiringSecureCoding: false)
                        
                            defaults.set(data, forKey: "SavedLyrics")

                    } catch {
                        print(error)
                    }
                
                    
                    
                }

Then in the view where I wish to display the attributedText in a text view I set up the code as follows:

    private func showUserLyrics() {

    let defaults = UserDefaults.standard
    let stringData = defaults.data(forKey: "SavedLyrics")
    
    do {
        let restored = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSAttributedString.self], from: stringData!)
        

        songLyricsResultsText.attributedText = restored as? NSAttributedString
        //homeLabel.attributedText = restored as? NSAttributedString

        print("Contents of songlyrics is as follows\(String(describing: restored))")
        print("I'm telling you the contents of your text view is:\(String(describing: songLyricsResultsText.attributedText))")


    } catch {
        print(error)
    }

    
}

The result of the print statements tells me that the array is being passed through and coming back as this:

was{
NSColor = "<UIDynamicCatalogColor: 0x282d27ed0; name = brandRed>";

},

the{
NSColor = "<UIDynamicCatalogColor: 0x282d45bd0; name = brandGreen>";

},

But my textView is having none of it and just printing out I'm telling you the contents of your text view is:Optional()

I feel like I'm missing a fundamental step between getting the array of data and assigning it in the correct way to the textview.attributedstring

If I don't pass in an array and just pass in the single attributedString value it will show in the text view. But obviously I want all the words to show and I'm completely stuck as to how to make that happen.

Any thoughts?

CodePudding user response:

You are storing data in NSAttributedString array but you are restoring in NSAttributedString object. I think this is the problem in your code instead of

songLyricsResultsText.attributedText = restored as? NSAttributedString

should be

songLyricsResultsText.attributedText = restored as? [NSAttributedString]

--UPDATE-- did you try this:

let lyricsArray = restored as? [NSAttributedString]    
songLyricsResultsText.attributedText = lyricsArray[0]

because restored data is of type Any

Thanks

CodePudding user response:

You are saving an array and casting it as NSAttributedString which will give you nil. You want all the words to show in the textView as green if it matches, then you don't create multiple AttributedStrings, instead you use:

let range = (lyric as NSString).range(of: theSentenceYouWantToColor)
let mutableAttributedString = NSMutableAttributedString(string: theTextContainingTheSentence)
mutableAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: yourColor, range: range)

do this for all the sentences you'd like to color while not creating a new mutableAttributedString (use the same instance), then you save the mutableAttributedString.attributedString() in UserDefaults

  • Related