I am seeing a strange issue with UITextView in latest iOS versions. As per my current understanding, it is only occurring in iOS 13. One of my users reported this on iOS 12.4.1, though I am unable to reproduce this on any pre iOS 13 devices.
I have created a small sample project in Xcode 11 to explain the issue. The project is targeting iOS 13. I am testing on an iPhone 8 running iOS 13.1.2 (17A860). The project contains a simple view controller with a textview. The TextView has autoCapitalizationType
as "Sentences". Then I implemented the delegate method shouldChangeTextInRange
method. See the code below
class ViewController: UIViewController {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.textView.delegate = self
self.textView.autocapitalizationType = .sentences
}
}
extension ViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
//I wanted to do some other modifications here, but for now just
//setting the user typed text manually and returning false
if let oldString = textView.text {
let newString = oldString.replacingCharacters(in: Range(range, in: oldString)!,
with: text)
textView.text = newString
}
return false
}
}
This is the whole code, except the storyboard and other project files. As you can see above, I am just setting the exact same text entered by the user into the textview manually, and then return false. But when I type, the first character gets added in caps as it should. The second character correctly gets added in small letter. From third character onwards everything is in caps. Moreover, the keyboard shift button automatically getting selected after each character is typed. A screenshot is attached.
Some other important points.
Can anyone suggest a fix/workaround for this issue?
The best workaround that I have found so far is to do the processing in textViewDidChange
instead.
The bug is also discussed here: Apple developer forum