Working on an issue that has been reported for Notepad Classic 2007 (currently free on App Store) I found that UITextView has problems keeping the scroll position when showing or hiding the keyboard.
This issue didn’t occur on iOS 7 and I wasted more than 5 hours trying to come up with a workaround. The problem is that showing and hiding the keyboard is causing superflous calls to layoutSubviews on the text view which causes it to change the contentSize and contentOffset. This gets further complicated by UITextView dynamically changing the contentSize as you scroll down through text that is longer than a few pages.
It is rare that I am so confounded by a bug, so I even opened a DTS call for it, hoping that there is a workaround for this problem.
Filed as rdar://20743459 and on Open Radar.
UITextView scroll position jumps around beginning/ending editing
A UITextView that has multiple pages worth of text content has an issue preserving the content offset beginning or ending editing. Showing or hiding the keyboard appears to trigger a superfluous -layoutSubviews which unnecessarily change the contentSize and contentOffset.
Steps to Reproduce
Launch the provided sample app
- Scroll down to the first arrow
- Align arrow with bottom of navigation bar
- Tap at the indicated position to start editing
- Re-align the arrow with bottom of navigation bar
- Tap on the resign button
- Scroll to very bottom of the text view
- Scroll as far up as possible to see the bottommost arrow over the keyboard.
- Tap to the right of the arrow and type a few characters. Again there is some weird flickering scroll movement,
but at least we see the cursor.
- Push the resign button again.
- Step 3 should not change scroll position
- Step 5 should not change scroll position
- Step 9 should change the scroll position such that the bottommost text is still visible (i.e. adjusting the inset should animate together with the frame of the keyboard)
- The scroll position shifts at all 3 indicated steps
- The user is getting confused and frustrated
I also found that the contentSize appears to change while scrolling downwards making it unreliable for use in calculations. As a workaround you can use -sizeThatFits which determines the actual contentSize. One problem here is though, that this also triggers a layoutSubviews.
Bonus Bug: If the keyboard is showing in the sample all, when run in simulator, the scrolling is very jerky and the scroll indicator jumps around (probably every time the contentSize is being adjusted)
The mentioned sample app is the TextViewScrollBug on https://github.com/cocoanetics/RadarSamples
Here is a video where I am demonstrating the issue via this app:
Categories: Bug Reports