I am trying to add a UIView into a UIScrollView without storyboard. I made some code with the given two files(CalcTypeView.siwft and CalcTypeViewController.swift) as below. However, as shown in the screenshot image, I can see the UIScrollView(gray color) while UIView(red color) does not appear on the screen. What should I do more with these code to make UIView appear? (I've already found many example code using single UIViewController, but what I want is UIView + UIViewController form to maintain MVC pattern)
1. CalcTypeView.swift
import UIKit
final class CalcTypeView: UIView {
private let scrollView: UIScrollView = {
let view = UIScrollView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .gray
view.showsVerticalScrollIndicator = true
return view
}()
private let contentView1: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .red
view.clipsToBounds = true
view.layer.cornerRadius = 10
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupScrollView()
setupContentView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupScrollView() {
self.addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
scrollView.widthAnchor.constraint(equalTo: self.widthAnchor),
scrollView.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor),
])
}
private func setupContentView() {
scrollView.addSubview(contentView1)
NSLayoutConstraint.activate([
contentView1.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 20),
contentView1.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -20),
contentView1.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 20),
contentView1.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -20),
])
}
}
2. CalcTypeViewController.swift
import UIKit
final class CalcTypeViewController: UIViewController {
private let calcTypeView = CalcTypeView()
override func viewDidLoad() {
super.viewDidLoad()
setupNavBar()
setupView()
}
private func setupNavBar() {
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.configureWithOpaqueBackground()
navigationBarAppearance.shadowColor = .clear
navigationController?.navigationBar.standardAppearance = navigationBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navigationBarAppearance
navigationController?.navigationBar.tintColor = Constant.ColorSetting.themeColor
navigationController?.navigationBar.prefersLargeTitles = false
navigationController?.setNeedsStatusBarAppearanceUpdate()
navigationController?.navigationBar.isTranslucent = false
navigationItem.scrollEdgeAppearance = navigationBarAppearance
navigationItem.standardAppearance = navigationBarAppearance
navigationItem.compactAppearance = navigationBarAppearance
navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "bookmark.fill"), style: .plain, target: self, action: #selector(addButtonTapped))
navigationItem.rightBarButtonItem?.tintColor = Constant.ColorSetting.themeColor
navigationItem.title = Constant.MenuSetting.menuName2
self.extendedLayoutIncludesOpaqueBars = true
}
override func loadView() {
view = calcTypeView
}
private func setupView() {
view.backgroundColor = .systemBackground
}
@objc private func addButtonTapped() {
let bookmarkVC = BookmarkViewController()
navigationController?.pushViewController(bookmarkVC, animated: true)
}
}
My Screenshot

A scroll view's
contentLayoutGuidedefines the size of the scrollable area of the scroll view. The default size is 0,0.In your code your
contentView1has no intrinsic size. It simply has a default size of 0,0. So your constraints are telling the scroll view to make itscontentLayoutGuideto be 40,40 (based on the 20 and -20 constants) and leave thecontentView1size as 0,0.If you setup
contentView1with specific width and height constraints then the scroll view's content size would be correct so thatcontentView1would scroll within the scroll view.A better example might be to add a UIStackView with a bunch of labels. Since the stack view will have an intrinsic size based on its content and setup, the
contentLayoutGuideof the scroll view will fit around the stack view's intrinsic size.