UITextView intrinsic size problem in iOS 16.0 Beta 3

Viewed 161

I am having trouble with an app that uses the intrinsic size of a UITextView on a physical iPhone 12 Pro Max running iOS 16.0 beta 3 (20A5312j). It seems to work on my other physical devices running production iOS versions (iOS 13 and later). And it works on the simulators.

The image on the left is what I would expect and what I am actually seeing on simulators and non-beta iOS devices. The image on the right is what I am seeing on Beta 3, with the first text view‘s intrinsic width not wide enough to fit the text, and the text view’s intrinsic height:

enter image description here

On the right, the intrinsic width of the top text field on the right image is too narrow to fit the text. The intrinsic height of the bottom text field is too short to fit the text.

And before people ask, a few observations:

  • Calling setNeedsLayout (or the like) does not fix it.
  • Calling setContentCompressionResistancePriority with .required (or what have you) has no impact.
  • The presence or absence of the border does not affect it either. I just included the border so you can see what is going on.
  • Adjusting textContainerInset adjusted the insets as expected, but manifested the same problem.
  • I am not looking for UILabel or other alternatives (as I need the data detectors).
  • I am not looking for non-autolayout workarounds (e.g., calculating size manually).

The question is merely (a) whether I am missing some property that avoids manifesting this behavior, and (b) whether others can reproduce the problem on Beta 3 physical devices. If others see the same behavior that I am, I am happy to file a bug report. I just want to make sure I am not overlooking anything obvious.


Here is the code that reproduced the above images:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let shortTextView = addTextView()
        shortTextView.text = "foo bar baz"

        let longTextView = addTextView()
        longTextView.text = "This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test."

        NSLayoutConstraint.activate([
            shortTextView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
            longTextView.topAnchor.constraint(equalTo: shortTextView.bottomAnchor, constant: 40)
        ])
    }

    /// Add text view to main view
    ///
    /// This:
    ///    1. Creates text view (with border so we can see its `frame`);
    ///    2. Adds to the main view; and
    ///    3. Adds horizontal constraints (with `lessThanOrEqual` for width to take advantage of text view’s intrinsic size).
    ///
    /// Note, even if you turn off the border, I see the same problem on physical device running iOS 16.0 Beta 3 (20A5312j).
    /// But the border lets you see what's going on.

    func addTextView() -> UITextView {
        let textView = UITextView()
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.isScrollEnabled = false
        textView.isEditable = false
        textView.layer.borderWidth = 1
        textView.layer.borderColor = UIColor.gray.cgColor

        view.addSubview(textView)

        let widthConstraint = NSLayoutConstraint(
            item: textView,
            attribute: .width,
            relatedBy: .lessThanOrEqual,
            toItem: view,
            attribute: .width,
            multiplier: 0.8,
            constant: 0
        )

        NSLayoutConstraint.activate([
            textView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            widthConstraint
        ])

        // note, vertical constraint not yet set ... will be set by caller

        return textView
    }
}
1 Answers

While I filed a bug report (FB10884711), it would appear that this was resolved in Beta 4.

Related