Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView data change swift

How can you detect a change of data in a UITextView with Swift? The following code does not do any detection.

I am declaring the UITextView :

@IBOutlet weak var bodyText: UITextView!

optional func textViewDidChange(_ textView: UITextView!) {
    println(bodyText.text)
}

Thanks Scott

like image 987
user3896519 Avatar asked Jul 31 '14 16:07

user3896519


5 Answers

You need to set UITextView delegate and implement textViewDidChange: method in it. Unfortunately, I do not know if swift documentation is available online. All the links go to the objective-c documentation.

The code will look like this: (updated for SWIFT 4.2)

class ViewController: UIViewController, UITextViewDelegate { //If your class is not conforms to the UITextViewDelegate protocol you will not be able to set it as delegate to UITextView

    @IBOutlet weak var bodyText: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        bodyText.delegate = self //Without setting the delegate you won't be able to track UITextView events
    }

    func textViewDidChange(_ textView: UITextView) { //Handle the text changes here
        print(textView.text); //the textView parameter is the textView where text was changed
    }
}
like image 200
Sergey Pekar Avatar answered Nov 19 '22 06:11

Sergey Pekar


For my case, I wanted the implementation to be independent from a UIViewController, so i dont need to assign a delegate just for text changes. Or even maybe there is some kind of validation on the UITextView, and you wanna contain it per field instead of a delegate managing a lot of complicated logic.

It requires to subclass UITextView, but its very much worth it imo:

class TextView: UITextView {

    convenience init() {
        self.init(frame: CGRect.zero, textContainer: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(textDidChangeNotification), name: UITextView.textDidChangeNotification , object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc func textDidChangeNotification(_ notif: Notification) {
        guard self == notif.object as? UITextView else {
            return
        }
        textDidChange()
    }

    func textDidChange() {
        // the text in the textview just changed, below goes the code for whatever you need to do given this event

        // or you can just set the textDidChangeHandler closure to execute every time the text changes, useful if you want to keep logic out of the class
        textDidChangeHandler?()
    }

    var textDidChangeHandler: (()->Void)?

}
like image 6
Lucas Chwe Avatar answered Nov 19 '22 04:11

Lucas Chwe


Set delegate of UITextView.Refer UITextViewDelegate

Write this in viewDidLoad

bodyText!.delegate = self
like image 5
codester Avatar answered Nov 19 '22 06:11

codester


For Swift 4:

func textViewDidChange(_ textView: UITextView) {
  // Your code here
}
like image 4
Andy Avatar answered Nov 19 '22 04:11

Andy


For Swift 4.2, you can add UITextViewTextDidChange, UITextViewTextDidBeginEditing & UITextViewTextDidEndEditing notification observers to a UITextView like this:

let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(textViewDidChange), name: NSNotification.Name.UITextViewTextDidChange , object: nil)
nc.addObserver(self, selector: #selector(textViewDidBeginEditing), name: NSNotification.Name.UITextViewTextDidBeginEditing , object: nil)
nc.addObserver(self, selector: #selector(textViewDidEndEditing), name: NSNotification.Name.UITextViewTextDidEndEditing , object: nil)

And the observers look like this:

@objc func textViewDidChange(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

@objc func textViewDidBeginEditing(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

@objc func textViewDidEndEditing(_ notif: Notification) {
    guard notif.object is UITextView else { return }
    // Do something
}

For Swift5, the format of the 'name' values are UITextView.textDidChangeNotification.

like image 2
JTODR Avatar answered Nov 19 '22 05:11

JTODR