KSigWyatt KSigWyatt - 4 months ago 27
iOS Question

Storing UITextView String / Text Data

So I am trying to create a view that displays a large text view that's editable. In the storyboard it's edited to display the text "Take your notes here (Swipe Down to dismiss the keyboard): " as a placeholder.

I'd like for it to remember when a user edits the text other than from that... so I made an if statement using != That comparator works for comparing strings in swift. I'm not sure that it will get approved by the app store review because they recommend isEqualToString().

Anyways the code below is for that view... It's not remembering the text entered if it's altered by the user from the placeholder. It recognizes that it was altered but when you go back to the view it displays the default placeholder again... Help?

import Foundation
import UIKit

class MessageNotesViewController: UIViewController, UITextViewDelegate {

@IBOutlet weak var messageNotes: UITextView!
@IBOutlet var swiped: UISwipeGestureRecognizer!

var placeholder = "Take your notes here (Swipe Down to dismiss the keyboard): "

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)

messageNotes.delegate = self
messageNotes.text = placeholder

}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

@IBAction func openIn(_ sender: AnyObject) {

print("Share with Social Media or Copy to Notes")
//let textToShare = messageNotes.attributedText

// let objectsToShare = [textToShare]
//let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)


//activityVC.popoverPresentationController?.sourceView = (sender as! UIView)
//self.present(activityVC, animated: true, completion: nil)


if let notes = messageNotes.text {
let avc = UIActivityViewController.init(activityItems: [notes], applicationActivities: nil)

avc.popoverPresentationController?.barButtonItem = sender as? UIBarButtonItem
self.present(avc, animated: true) {
print("completed")
}
}
}

func touchesBegan(_ messageNotes: UITextField) -> Bool {
self.view.endEditing(true)
return false
}


//let defaults = NSUserDefaults.

override func viewWillDisappear(_ animated: Bool) {
//PrepareForSegue didn't quite work
print("View Will Disappear")

//Testing if the user has entered any text if so preserve entered text
if messageNotes.text != placeholder {

//viewDidLoad(typedText)
print("the user altered the text in some way. \n")

placeholder = messageNotes.text
// assigns new placeholder
}
else{
// do something else - if needed
}
}
}

//Sub class decleration for ActivityForNotesViewController as called in openIn
class ActivityForNotesViewController: UIActivityViewController {

internal func _shouldExcludeActivityType(_ activity: UIActivity) -> Bool {
let activityTypesToExclude = [
]

if let actType = activity.activityType() {
if activityTypesToExclude.contains(actType) {
return true
}
else if super.excludedActivityTypes != nil {
return super.excludedActivityTypes!.contains(actType)
}
}
return false
}
}


There were some compiling errors when trying to implement the answer below.

In the viewWillAppear function the compiler says "Cannot call value of non-function type 'UserDefaults'" - the compiler highlights the line
if let newText
line with the
UserDefaults.standardUserDefaults()
underlined in red.

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)

messageNotes.delegate = self
messageNotes.text = placeholder

if let newText = UserDefaults.standardUserDefaults().objectForKey("textKey"){
if newText.length > 0 {
messageNotes.text = newText
}
}

}


The Same compiling error is found in the viewWillDisappear function:

override func viewWillDisappear(_ animated: Bool) {
//Prepare for segue didn't quite work for what I need
print("View Will Disappear")

//Testing if the user has entered any text if so preserve entered text
if messageNotes.text != placeholder {

//viewDidLoad(typedText)
print("the user altered the text in some way. \n")

UserDefaults.standardUserDefaults().setObject(messageNotes.text!, forKey:"textKey")

// assigns new placeholder
}
else{
// do something else - if needed
}
}
}

Answer

You need to save the changes somewhere, I'd recommend UserDefaults, which is a good way to save user preferences, and other small pieces of data.

I'd replace this in viewWillDisappear:

placeholder = messageNotes.text

with

UserDefaults.standardUserDefaults().set(messageNotes.text!, forKey:"textKey")

And in viewWillAppear I'd add:

messageNotes.text = placeholder
if let newText = UserDefaults.standardUserDefaults().object("textKey"){
    if newText.length > 0 {
        messageNotes.text = newText as! String
    }
}