title: How do I prevent the scroll view from scrolling to the start when editing a big text view in it?
body: <p>I am trying to make an editable, multiline, <code>UITextView</code> that can horizontally scroll. From multiple answers I found (<a href="https://stackoverflow.com/questions/2201254/prevent-word-wrap-with-uitextview/27758780">1</a>, <a href="https://stackoverflow.com/questions/26674030/uitextview-disable-wrapping">2</a>, <a href="https://stackoverflow.com/questions/43322541/swift-scroll-a-uitextview-horizontally">3</a>), it seems like I should put the <code>UITextView</code> into a <code>UIScrollView</code>, so I did exactly that. However, the editing experience turned out to be awful.</p>
  <p>Here is an MCVE:</p>
  <pre><code>class MyViewController: UIViewController {
      
      // connect this outlet to a scroll view that covers the whole screen
      @IBOutlet var scrollView: UIScrollView!
      var textView: UITextView!
      
      override func viewDidLoad() {
          setupTextView()
          scrollView.addSubview(textView)
      }
      
      let font = UIFont.monospacedSystemFont(ofSize: 23, weight: .regular)
      func setupTextView() {
  
          // My text view is going to contain a maximum of 80x25 characters, so here
          // I am calculating how much space that is going to take up
          let line = String(repeating: &quot;a&quot;, count: 81)
          let fullText = Array(repeating: line, count: 26).joined(separator: &quot;\n&quot;)
          let unroundedSize = (fullText as NSString).size(withAttributes: [
              .font: font
          ])
          let size = CGSize(width: ceil(unroundedSize.width), height: ceil(unroundedSize.height))
          textView = UITextView(frame: CGRect(origin: .zero, size: size))
          
          scrollView.contentSize = size
          textView.spellCheckingType = .no
          textView.dataDetectorTypes = []
          textView.font = font
  
          // dummy text
          textView.text = &quot;&quot;&quot;
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras et finibus turpis.
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras et finibus turpis.
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras et finibus turpis.
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras et finibus turpis.
          &quot;&quot;&quot;
  
          // the text view do not need to scroll. All the scrolling is done
          // by the scroll view
          textView.isScrollEnabled = false
      }
  }
  </code></pre>
  <p>To see how awful the editing experience is, put the cursor at the end of the text, then try deleting some of the text at the end of the string by holding down the delete key. The scroll view &quot;flickers&quot; between where the cursor is, and the far left of the text view, i.e. these two states:</p>
  <p><a href="https://i.stack.imgur.com/Rkx9j.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Rkx9j.png" alt="enter image description here" /></a></p>
  <p><a href="https://i.stack.imgur.com/S08jw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/S08jw.png" alt="enter image description here" /></a></p>
  <p>I tried to scroll to the cursor whenever the cursor moved by doing:</p>
  <pre><code>func textViewDidChangeSelection(_ textView: UITextView) {
      guard let range = textView.selectedTextRange else { return }
      let rect = textView.caretRect(for: range.end)
      guard !CGRect(origin: scrollView.contentOffset, size: scrollView.visibleSize).intersects(rect) else { return }
      scrollView.scrollRectToVisible(rect, animated: true)
  }
  </code></pre>
  <p>but that didn't improve the awful behaviour of the delete key at all.</p>
  <p>How can I prevent the scroll view from scrolling to the start?</p>