2

When I tap from one text field to another, it scrolls so that the previous text view is in focus. I've tried to respond to this by observing keyboard change notification and noticed that the UIResponder.keyboardWillChangeFrameNotification is getting called twice. Once while the first text view is still first responder, and once while the second text view is first responder.

Scroll Problems

If anyone want's to take a stab at this I created the minimum code to reproduce the issue I'm seeing. Start a new single page app and paste this into ViewController.swift.

import UIKit

class ViewController: UIViewController {

    override func loadView() {
        view = ScrollView()
    }
}

class ScrollView: UIScrollView {

    lazy var stack: UIStackView = {
        let stack = UIStackView()
        stack.backgroundColor = .systemGroupedBackground
        stack.axis = .vertical
        stack.spacing = 32
        for number in 1...50 {
            let textField = UITextField()
            textField.text = "\(number)"
            textField.borderStyle = .roundedRect
            textField.heightAnchor.constraint(equalToConstant: 44).isActive = true
            stack.addArrangedSubview(textField)
        }
        return stack
    }()

    init() {
        super.init(frame: .zero)
        addSubview(stack)
        stack.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            stack.topAnchor.constraint(equalTo: topAnchor),
            stack.bottomAnchor.constraint(equalTo: bottomAnchor),
            stack.leadingAnchor.constraint(equalTo: leadingAnchor),
            stack.trailingAnchor.constraint(equalTo: trailingAnchor),
            stack.widthAnchor.constraint(equalTo: widthAnchor)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
B Roy Dawson
  • 611
  • 1
  • 6
  • 18

1 Answers1

2

I can't figure out why iOS 14 is behaving this way, and if it's intended or a bug. The way that I was able to work around it was to subclass UIScrollView and override setContentOffset to do nothing. Here is an example of what I'm talking about.

class ScrollView: UIScrollView {

    func forceContentOffset(_ contentOffset: CGPoint, animated: Bool) {
        super.setContentOffset(contentOffset, animated: animated)
    }

    override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
        // Intentially left blank to block the system from changing the content offset
    }
}

This allows you to manual determine when to scroll the scroll view, but it requires implanting any automatic behavior that you want to keep on your own.

B Roy Dawson
  • 611
  • 1
  • 6
  • 18