Implementing UIScrollView using constraints without using content size

UIScrollView is a view that allows the scrolling and zooming of its contained views.

UIScrollView is the superclass of several UIKit classes including UITableView and UITextView.

The central notion of a UIScrollView object (or, simply, a scroll view) is that it is a view whose origin is adjustable over the content view. It clips the content to its frame, which generally (but not necessarily) coincides with that of the application’s main window. A scroll view tracks the movements of fingers and adjusts the origin accordingly. The view that is showing its content “through” the scroll view draws that portion of itself based on the new origin, which is pinned to an offset in the content view. The scroll view itself does no drawing except for displaying vertical and horizontal scroll indicators. The scroll view must know the size of the content view so it knows when to stop scrolling; by default, it “bounces” back when scrolling exceeds the bounds of the content.

You can read more about UIScrollView here https://developer.apple.com/documentation/uikit/uiscrollview

Before starting this, please try read through this article which has a good tutorial on using auto layout constraints.

Image showing a scrollview in action
Scrollview in action.

Many articles suggest you to use content size when using a scroll view. In this article, I will be using constraints to show that it’s not needed.

This is a continuation to my previous article on using constraints. The trick to make scrollview work is by using the bottom and top anchor.

To begin, let’s start by adding a scroll view.

let scrollview = UIScrollView()
scrollview.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollview)
scrollview.backgroundColor = .clear
scrollview.heightAnchor.constraint(equalToConstant: 100).isActive = true
scrollview.topAnchor.constraint(equalTo: roundView.bottomAnchor, constant: 10).isActive = true
scrollview.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
scrollview.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
scrollview.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true

As usual we start by using the leading and trailing anchors to stretch the scroll view to the screen size. Also make a note of the bottom anchor.

Next let’s add content to this scroll view. This can be done as shown below. The code to display looks bad, but this is just a demo code.

let logs = ["this is a line1", "whats your name2", "tell me something3", "calgary toronto lisbon4", "exportFinished5","this is a line6", "whats your name7", "tell me something8", "calgary toronto lisbon8", "exportFinished10101","this is a line999", "whats your name", "tell me something", "calgary toronto lisbon12", "exportFinished22","this is a line88", "whats your name99", "tell me something00", "calgary toronto lisbon11","exportFinished22", "exportFinished14"]
var previousBottomAnchor = scrollview.topAnchor
var firstCell = true
for log in logs {
	let label = UILabel()
	label.text = log
	label.isUserInteractionEnabled = false
	scrollview.addSubview(label)
	label.translatesAutoresizingMaskIntoConstraints = false
	label.heightAnchor.constraint(equalToConstant: 40).isActive = true
	label.backgroundColor = .clear
	label.leadingAnchor.constraint(equalTo: scrollview.leadingAnchor, constant: 10).isActive = true
	label.trailingAnchor.constraint(equalTo: scrollview.trailingAnchor, constant: 10).isActive = true
	if firstCell {
               firstCell = false
               label.topAnchor.constraint(equalTo: scrollview.topAnchor).isActive = true
               previousBottomAnchor = label.bottomAnchor
	       } else {
              label.topAnchor.constraint(equalTo: previousBottomAnchor).isActive = true
              previousBottomAnchor = label.bottomAnchor
              if log == "exportFinished14" {
	     label.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor).isActive = true
        }
	}
}

Pay special attention to the code below.

This is the snippet which stretches your scrollview all the way to the bottom of the screen. Basically I am making the bottom anchor of the last label equal to the bottom anchor of the scroll view. This does the trick. The magic of using constraints lies in joining all the constraints of the views to form a single chain. roundview to scrollview to labelview

if log == "exportFinished14" {
	        label.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor).isActive = true
        }

Leave a Reply

Your email address will not be published. Required fields are marked *