diff --git a/MessageViewController/MessageAutocompleteController.swift b/MessageViewController/MessageAutocompleteController.swift
index 806eb38..e535e46 100644
--- a/MessageViewController/MessageAutocompleteController.swift
+++ b/MessageViewController/MessageAutocompleteController.swift
@@ -233,7 +233,7 @@ public final class MessageAutocompleteController: MessageTextViewListener {
         preserveTypingAttributes(for: textView)
     }
     
-    public func willChangeRange(textView: MessageTextView, to range: NSRange) {
+    public func willChangeText(textView: MessageTextView, inRange range: NSRange, to: String) -> Bool {
         
         // range.length == 1: Remove single character
         // range.lowerBound < textView.selectedRange.lowerBound: Ignore trying to delete
@@ -248,6 +248,7 @@ public final class MessageAutocompleteController: MessageTextViewListener {
             if let isAutocomplete = attribute[NSAttributedAutocompleteKey] as? Bool, isAutocomplete {
                 // Remove the autocompleted substring
                 let lowerRange = NSRange(location: 0, length: range.location + 1)
+                var shouldPreserveTypedText = true
                 textView.attributedText.enumerateAttribute(NSAttributedAutocompleteKey, in: lowerRange, options: .reverse, using: { (_, range, stop) in
 
                     // Only delete the first found range
@@ -258,9 +259,12 @@ public final class MessageAutocompleteController: MessageTextViewListener {
                     textView.selectedRange = NSRange(location: range.location, length: 0)
                     self.textView.textViewDidChange(textView)
                     self.preserveTypingAttributes(for: textView)
+                    shouldPreserveTypedText = false
                 })
+                return shouldPreserveTypedText
             }
         }
+        return true
     }
 
 }
diff --git a/MessageViewController/MessageTextView.swift b/MessageViewController/MessageTextView.swift
index 3399d65..82c9dae 100644
--- a/MessageViewController/MessageTextView.swift
+++ b/MessageViewController/MessageTextView.swift
@@ -10,7 +10,7 @@ import UIKit
 public protocol MessageTextViewListener: class {
     func didChange(textView: MessageTextView)
     func didChangeSelection(textView: MessageTextView)
-    func willChangeRange(textView: MessageTextView, to range: NSRange)
+    func willChangeText(textView: MessageTextView, inRange: NSRange, to: String) -> Bool
 }
 
 open class MessageTextView: UITextView, UITextViewDelegate {
@@ -134,8 +134,13 @@ open class MessageTextView: UITextView, UITextViewDelegate {
     }
     
     public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
-        enumerateListeners { $0.willChangeRange(textView: self, to: range) }
-        return true
+        // If listener changes text then subsequent listeners will probably get incorrect affected range
+        // and text as they were changed by previous listener. So be careful playing with textView
+        var shouldChange = true
+        // if at least one listener changes text and needs to ignore typed text then this method returns
+        // that just typed text needs to be ignored
+        enumerateListeners { shouldChange = shouldChange && $0.willChangeText(textView: self, inRange: range, to: text) }
+        return shouldChange
     }
 
 }
diff --git a/MessageViewController/MessageView.swift b/MessageViewController/MessageView.swift
index b01beb5..f6434d4 100644
--- a/MessageViewController/MessageView.swift
+++ b/MessageViewController/MessageView.swift
@@ -336,6 +336,8 @@ public final class MessageView: UIView, MessageTextViewListener {
         delegate?.selectionDidChange(messageView: self)
     }
     
-    public func willChangeRange(textView: MessageTextView, to range: NSRange) {}
+    public func willChangeText(textView: MessageTextView, inRange: NSRange, to: String) -> Bool {
+        return true
+    }
 
 }