Why does shouldChangeTextInRange get called multiple times using predictive input?

I got this same issue. It appears that with predictive text, setting textView.text in that delegate method triggers an immediate call to that delegate method again (this only happens with predictive text as far as I know).

I fixed it by just surrounding my textView changes with a guard:

private var hack_shouldIgnorePredictiveInput = false

func textView(textView: UITextView!, shouldChangeTextInRange range: NSRange, replacementText text: String!) -> Bool {
    if hack_shouldIgnorePredictiveInput {
        hack_shouldIgnorePredictiveInput = false
        return false
    }

    hack_shouldIgnorePredictiveInput = true

    textView.text = "" // Modify text however you need. This will cause shouldChangeTextInRange to be called again, but it will be ignored thanks to hack_shouldIgnorePredictiveInput

    hack_shouldIgnorePredictiveInput = false

    return false
}