简体   繁体   English

如何将UIView放入Swift中的UIScrollView?

[英]How to put UIView inside UIScrollView in Swift?

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.我正在尝试将UIView添加到没有 storyboard 的UIScrollView中。我使用给定的两个文件(CalcTypeView.siwft 和 CalcTypeViewController.swift)编写了一些代码,如下所示。 However, as shown in the screenshot image, I can see the UIScrollView (gray color) while UIView (red color) does not appear on the screen.但是,如屏幕截图所示,我可以看到UIScrollView (灰色),而UIView (红色)没有出现在屏幕上。 What should I do more with these code to make UIView appear?我应该如何处理这些代码才能使UIView出现? (I've already found many example code using single UIViewController , but what I want is UIView + UIViewController form to maintain MVC pattern) (我已经找到了许多使用单个UIViewController的示例代码,但我想要的是UIView + UIViewController形式来维护 MVC 模式)

1. CalcTypeView.swift 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 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 contentLayoutGuide defines the size of the scrollable area of the scroll view.滚动视图的contentLayoutGuide定义滚动视图的可滚动区域的大小。 The default size is 0,0.默认大小为 0,0。

In your code your contentView1 has no intrinsic size.在您的代码中,您的contentView1没有固有大小。 It simply has a default size of 0,0.它的默认大小为 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.因此,您的约束告诉滚动视图使其contentLayoutGuide为 40,40(基于 20 和 -20 常量)并将contentView1大小保留为 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.如果您使用特定的宽度和高度约束设置contentView1 ,则滚动视图的内容大小将是正确的,以便contentView1将在滚动视图内滚动。

A better example might be to add a UIStackView with a bunch of labels.一个更好的例子可能是添加一个带有一堆标签的 UIStackView。 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.由于堆栈视图将具有基于其内容和设置的固有大小,因此滚动视图的contentLayoutGuide将适合堆栈视图的固有大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM