Home > Back-end >  How to put UIView inside UIScrollView in Swift?
How to put UIView inside UIScrollView in Swift?

Time:12-30

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

enter image description here

CodePudding user response:

A scroll view's contentLayoutGuide defines the size of the scrollable area of the scroll view. The default size is 0,0.

In your code your contentView1 has no intrinsic size. It simply has a default size of 0,0. So your constraints are telling the scroll view to make its contentLayoutGuide to be 40,40 (based on the 20 and -20 constants) and leave the contentView1 size as 0,0.

If you setup contentView1 with specific width and height constraints then the scroll view's content size would be correct so that contentView1 would 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 contentLayoutGuide of the scroll view will fit around the stack view's intrinsic size.

  • Related