簡體   English   中英

Swift:UIStackView 重疊所有視圖而不是垂直堆疊它們

[英]Swift: UIStackView Overlapping all Views instead of Stacking them Vertically

我正在嘗試為我的應用程序創建一個統計頁面,該頁面將根據用戶擁有的數據類型動態創建各種圖表。 為此,我根據本教程堆疊多個 ViewController: https : //swiftwithmajid.com/2019/02/27/building-complex-screens-with-child-viewcontrollers/

我遇到了一個問題,即 ViewController 的視圖作為一個排列的子視圖添加到主 StackView,但它不是垂直堆疊視圖並允許我滾動瀏覽它們,它只是將它們堆疊在 z-方向。

在此處輸入圖片說明

這是 StackViewController 代碼:

class StackViewController: UIViewController {
    private let scrollView = UIScrollView()
    private let stackView = UIStackView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(scrollView)
        scrollView.addSubview(stackView)
        setupConstraints()
        stackView.axis = .vertical
    }

    private func setupConstraints() {
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        stackView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
                    scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
                    scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
                    scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                    scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
                    stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
                    stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
                    stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            stackView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor)
                    ])
    }
}

extension StackViewController {
    func add(_ child: UIViewController) {
        addChild(child)
        stackView.addArrangedSubview(child.view)
        print(child.view!)
        child.didMove(toParent: self)
    }

    func remove(_ child: UIViewController) {
        guard child.parent != nil else {
            return
        }

        child.willMove(toParent: nil)
        stackView.removeArrangedSubview(child.view)
        child.view.removeFromSuperview()
        child.removeFromParent()
    }
}

這是我創建每個視圖控制器並將其添加到 StackViewController 的地方。 現在,我運行一個循環並一遍又一遍地添加單個視圖控制器的副本:

class PrototypeViewController: StackViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        for _ in 0...10 {
            setupUI()
        }
    }

    private func setupUI() {
        let storyboard = UIStoryboard(name: "ConsistencyGraph", bundle: .main)
        let consistencyGraphVC = storyboard.instantiateViewController(identifier: "ConsistencyGraphVC") as! ConsistencyGraphVC
        add(consistencyGraphVC)
        consistencyGraphVC.setupUI(name: "sessionName", consistencyPercentage: 30, ballsHit: 10)
    }
}

這是視圖控制器代碼:

class ConsistencyGraphVC: UIViewController {

    @IBOutlet weak var mainView: UIView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var ballsHitLabel: UILabel!
    @IBOutlet weak var pieChartView: PieChartView!
        
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    open func setupUI(name: String, consistencyPercentage: Double, ballsHit: Int) {
        displayName(name:name)
        drawPieChart(consistencyPercentage: consistencyPercentage)
        displayBallsHit(ballsHit: ballsHit)
    }
    
    private func displayName(name: String) {
        let prefix = "Consistency: "
        let title = prefix + name
        titleLabel.text = title
    }
    
    private func displayBallsHit(ballsHit: Int) {
        ballsHitLabel.text = String(ballsHit)
    }
    
    private func drawPieChart(consistencyPercentage: Double) {
        let maxPercent:Double = 100
        let remainingPercent = maxPercent - consistencyPercentage
        let dataEntry = [PieChartDataEntry(value: consistencyPercentage, data: String(consistencyPercentage)), PieChartDataEntry(value: remainingPercent, data: nil)]
        let dataSet = PieChartDataSet(entries: dataEntry)
        let chartData = PieChartData(dataSet: dataSet)
        let color1 = randomColor()
        let color2 = randomColor()
        dataSet.colors = [color1, color2]
        pieChartView.data = chartData
    }
    
    private func randomColor() -> UIColor {
        let red = Double(arc4random_uniform(256))
        let green = Double(arc4random_uniform(256))
        let blue = Double(arc4random_uniform(256))
        let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
        return color
    }
}

起初,我認為這是因為 View Controller 的大小可能不明確。 然后我硬編碼了每個視圖控制器的寬度和高度,但仍然沒有運氣。

非常感謝任何和所有幫助! 我不知道這怎么可能。

先感謝您!

您忘記了 ScrollView 中 StackView 的一些必需約束。 你只有trailing, top, and bottom是不夠的。

  • 正確的:
stackView.leadingAnchor
stackView.trailingAnchor
stackView.topAnchor
stackView.bottomAnchor
stackView.widthAnchor

我終於找到了解決方案!

我需要添加:

child.view.heightAnchor.constraint(equalToConstant: child.view.frame.size.height).isActive = true

到這里的 StackViewController:

func add(_ child: UIViewController) {
        addChild(child)
        child.view.heightAnchor.constraint(equalToConstant: child.view.frame.size.height).isActive = true
        stackView.addArrangedSubview(child.view)
        child.didMove(toParent: self)
    }

我不確定為什么會這樣。 我已經對視圖的高度進行了硬編碼,但是 stackView 還希望我在添加視圖之前對其進行約束。

我希望這對未來的人有所幫助! 多年來,我一直在用頭撞牆……

暫無
暫無

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

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