Introduction: The "Magic" of UIScrollView That Stops Working
\n\nHave you ever encountered a situation: you add a UIScrollView to your Swift project, set up Auto Layout, run the app — and nothing scrolls? Or, even worse, Xcode gives a mysterious error: "UIScrollView scrollable content size ambiguity"? If so — you are not alone. This question has gathered thousands of views on Stack Overflow, and today we will finally figure out what's going on.
Imagine: you are creating a screen with a long registration form or an article that doesn't fit on one screen. You add a UIScrollView, put all the elements in it, set up constraints — and... silence. The scroll doesn't work. Sound familiar? Welcome to the club of developers who have cursed Auto Layout for being "unintuitive."
In reality, the Content Size Ambiguity problem is not an iOS bug, but a logical trap. The system simply doesn't know how large your content should be. In this tutorial, we will break down the cause, three solutions, and write real working code. Let's go!
\n\nWhat is Content Size Ambiguity and Why Does It Occur?
\n\nUIScrollView is a special beast in the UIKit world. Unlike regular views, it does not determine its size from the constraints of its child elements. Instead, it uses the contentSize property (type CGSize), which indicates how large the "under the hood" canvas is. If contentSize is less than or equal to the size of the UIScrollView itself, scrolling is... well, not needed.
The Scrollable Content Size Ambiguity error occurs when Auto Layout cannot unambiguously calculate contentSize based on the constraints inside the scroll view. Typical scenarios:
- \n
- You haven't set constraints for the height or width of the inner content. \n
- The constraints are "floating" (e.g., no connection to the top and bottom of the scroll view). \n
- You are using a
UIStackViewinside aUIScrollViewbut haven't configured its size. \n - You forgot that
UIScrollViewrequires a complete chain of constraints from edge to edge. \n
In the Xcode console, you will see something like:
\nUnable to simultaneously satisfy constraints.\nWill attempt to recover by breaking constraint.\n...\nUIScrollView scrollable content size ambiguity\n\nSounds scary, but the solution is simple. Let's write some code.
\n\nStep 1: Create a Project and Add UIScrollView
\n\nOpen Xcode, create a new project with the App template (iOS, Swift). Let's name it, for example, ScrollFixDemo. Go to ViewController.swift and replace all the code with the following:
import UIKit\n\nclass ViewController: UIViewController {\n \n override func viewDidLoad() {\n super.viewDidLoad()\n setupScrollView()\n }\n \n private func setupScrollView() {\n // 1. Create UIScrollView\n let scrollView = UIScrollView()\n scrollView.translatesAutoresizingMaskIntoConstraints = false\n scrollView.backgroundColor = .systemGray6\n view.addSubview(scrollView)\n \n // 2. Constraints for scrollView (fill the entire screen)\n NSLayoutConstraint.activate([\n scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),\n scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),\n scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),\n scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)\n ])\n \n // 3. Create contentView - a container for all content\n let contentView = UIView()\n contentView.translatesAutoresizingMaskIntoConstraints = false\n contentView.backgroundColor = .white\n