Search code examples
iosswifttextviewuitextviewdelegate

textViewDidChangeSelection method thinks textView.text is empty


For various reasons, I need to access the text in a textview whenever a selection is changed, so I have implemented the delegate method textViewDidChangeSelection() to do so. For some reason though, when I try to access textView.text from within this method, sometimes it comes back as empty even when it's not. Take this bit of code for example.

func textViewDidChangeSelection(_ textView: UITextView) {
    print("Called textViewDidChangeSelection")

    if textView.text.isEmpty {
        print("textview is empty")
    } else {
        print("textview is not empty")
    }
}

Using this example in my code, I click on a textView that is NOT empty and sometimes it comes back with "textview is empty." It seems like it tends to happen most often immediately after re-running the simulator and clicking on any textView, but I've also seen it happen when just clicking on a textView for the first time (after having clicked on some other textView) or when I segue back to my UIView containing the textViews from some other view.

Does anyone know why this happens?


Solution

  • textViewDidChangeSelection(_ textView: UITextView)
    

    is called when the text selection changes, not necessarily just when another textView is selected. In fact in the olden days the selectedRange property of the textView used to return zero (indicating an insertion) but now (according to Apple) the length of the selection range may be non-zero. When you click away from a textView your delegate method may be firing for the initial textView (the one you're leaving) which would give you the result you're seeing, if it's empty.

    Try giving your textView tags and using:

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        print("Selected \(textView.tag)")
    
        return true
    }
    

    To see if it solves your problem. Of course tags are just a quick and dirty check and you'd probably use a more flexible textView identification in your app.