簡體   English   中英

無法向 scrollView 添加任何子視圖

[英]Cannot add any subview to scrollView

我感到很困惑。 我無法讓任何子視圖出現在滾動視圖中

具體來說,我想添加另一個視圖控制器的視圖,但我什至無法添加任何標簽或任何東西。 我也看不到視圖調試器層次結構中的任何子視圖

我究竟做錯了什么??

import UIKit

class MainViewController: UIViewController {

    var scrollView: UIScrollView {
        let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        scrollView.isPagingEnabled = true
        scrollView.backgroundColor = .orange
        scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height:  UIScreen.main.bounds.height)
        return scrollView
    }

    var leftViewController: UIViewController {
        let vC = UIViewController()
        vC.view.backgroundColor = .purple
        return vC
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        leftViewController.view.frame = .init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        addChild(leftViewController)
        scrollView.addSubview(leftViewController.view)
        leftViewController.didMove(toParent: self)
    }
}

可以通過自動布局實現我想要的效果,但仍然是硬編碼寬度。

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(scrollViewContainer)
        scrollViewContainer.addArrangedSubview(redView)
        scrollViewContainer.addArrangedSubview(blueView)
        scrollViewContainer.addArrangedSubview(greenView)

        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        scrollViewContainer.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        scrollViewContainer.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
        scrollViewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        scrollViewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }

    let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.isPagingEnabled = true
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()

    let scrollViewContainer: UIStackView = {
        let view = UIStackView()
        view.axis = .horizontal
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    let redView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .red
        return view
    }()

    let blueView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .blue
        return view
    }()

    let greenView: UIView = {
        let view = UIView()
        view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
        view.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height).isActive = true
        view.backgroundColor = .green
        return view
    }()
}

如果不出意外,如果您在原始問題中提供了第一個示例,那么您正在使用計算屬性。 每次引用它們時,它們都會返回一個新實例。 您應該創建這些存儲屬性:

var scrollView: UIScrollView = {
    let scrollView = UIScrollView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    scrollView.isPagingEnabled = true
    scrollView.backgroundColor = .orange
    scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width * 3.0, height:  UIScreen.main.bounds.height)
    return scrollView
}()

var leftViewController: UIViewController = {
    let vC = UIViewController()
    vC.view.backgroundColor = .purple
    return vC
}()

請注意=並在末尾添加()以指定它們已使用閉包進行初始化。

計算屬性的問題在於,由於每個引用都返回一個新實例,因此您調整其frame的子視圖控制器的視圖與您添加為子視圖的視圖不同。 並且您添加子項的滾動視圖與您添加到容器視圖控制器的滾動視圖不同。


在您修改后的問題中,您使用約束共享了代碼。 如果使用約束,請確保將所有相關視圖的translatesAutoresizingMaskIntoConstraints設置為false 否則,它會自動將視圖的自動調整大小掩碼轉換為與您手動添加的新約束沖突的約束。

並且您還應該避免使用constraint(equalToConstant:) ,使用constraint(equalTo:) ,盡可能引用主視圖。 例如:

class ViewController: UIViewController {
    let scrollView: UIScrollView = {
        let view = UIScrollView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.isPagingEnabled = true
        return view
    }()

    let redView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .green
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(redView)
        scrollView.addSubview(greenView)

        NSLayoutConstraint.activate([
            // set the scroll view to be the size of the main view

            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),

            // set the subviews to be the size of the main view, too

            redView.widthAnchor.constraint(equalTo: view.widthAnchor),
            redView.heightAnchor.constraint(equalTo: view.heightAnchor),

            greenView.widthAnchor.constraint(equalTo: view.widthAnchor),
            greenView.heightAnchor.constraint(equalTo: view.heightAnchor),

            // now dictate where these subviews are in the scroll view vertically ...

            redView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            greenView.topAnchor.constraint(equalTo: scrollView.topAnchor),

            redView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            greenView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),

            // ... and horizontally

            redView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            greenView.leadingAnchor.constraint(equalTo: redView.trailingAnchor),
            greenView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor)
        ])
    }
}

坦率地說,既然你在談論全屏子視圖控制器,我會完全放棄這段代碼,只使用UIPageViewController (這不僅讓我們擺脫了調整子視圖控制器頂級視圖大小的業務,而且讓我們做一個更有效的“及時”創建子視圖控制器)。

但我想展示如果您手動執行此操作,約束會是什么樣子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM