这个 StackView 有什么问题?

What is wrong with this StackView?

我的 StackView 有什么问题? 这是代码:

class PushUpViewController: UIViewController {

        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .white
            setUpStackView()
        }
        
            func setUpStackView() {
            // SetUp StackView:
            stackView.translatesAutoresizingMaskIntoConstraints = false
            stackView.axis = .vertical
                stackView.alignment = .center
                stackView.distribution = .fillProportionally
            stackView.spacing = 50
            view.addSubview(stackView)
            
            // SetUp StackView Constraints:
                stackView.pin(to: view)
                stackView.setCustomSpacing(50, after: PushUpButton)
                stackView.setCustomSpacing(100, after: TimeLabel)
            
            // Set Elements to StackView:
            stackView.addArrangedSubview(TimeLabel)
            stackView.addArrangedSubview(PushUpButton)
            stackView.addArrangedSubview(secondStackView)
            

       // SetUp PushUpButton:
           PushUpButton.backgroundColor = .white
           PushUpButton.setTitle("\(count)", for: .normal)
           PushUpButton.setTitleColor(.systemGray, for: .normal)
           PushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
           
           
           PushUpButton.translatesAutoresizingMaskIntoConstraints = false
           
                PushUpButton.heightAnchor.constraint(equalToConstant: 300).isActive = true
                PushUpButton.widthAnchor.constraint(equalToConstant: 150).isActive = true
           
       
    // SetUp TimeLabel
           TimeLabel.textAlignment = .center
                   TimeLabel.text = "\(counter)"
                   TimeLabel.textColor = .black
                   TimeLabel.font = .boldSystemFont(ofSize: 30)
                   self.view.addSubview(TimeLabel)
                   
                   TimeLabel.translatesAutoresizingMaskIntoConstraints = false
                   
       
                TimeLabel.widthAnchor.constraint(equalToConstant: 300).isActive = true
                TimeLabel.heightAnchor.constraint(equalToConstant: 200).isActive = true
        
      
            
            
            // SetUp SecondStackView
            secondStackView.translatesAutoresizingMaskIntoConstraints = false
            secondStackView.axis = .horizontal
            secondStackView.alignment = .center
            secondStackView.distribution = .fillEqually
                secondStackView.spacing = 20
            
            
            // SetUp SecondStackView Constrains
                secondStackView.heightAnchor.constraint(equalToConstant: 50).isActive = true
                secondStackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -15).isActive = true
            
            
            // Set Elements:
            secondStackView.addArrangedSubview(breakButton)
            secondStackView.addArrangedSubview(stopbutton)
            
            //SetUp BreakButton
                  breakButton.backgroundColor = .lightGray
                  breakButton.setTitle("Break", for: .normal)
                  breakButton.setTitle("Start", for: .selected)
            breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
                  breakButton.setTitleColor(.white, for: .normal)
                  breakButton.layer.cornerRadius = 12
                  breakButton.layer.borderWidth = 1
                  breakButton.layer.borderColor = UIColor.white.cgColor
//               breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
                  
                  
                  breakButton.translatesAutoresizingMaskIntoConstraints = false
                  
               NSLayoutConstraint.activate([
                  breakButton.widthAnchor.constraint(equalToConstant: 150),
                  breakButton.heightAnchor.constraint(equalToConstant: 50)
               ])
              
                
               
              
              // SetUp StopButton:
                  stopbutton.backgroundColor = .systemRed
                  stopbutton.setTitle("Stop", for: .normal)
                  stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
                  stopbutton.setTitleColor(.white, for: .normal)
                  stopbutton.layer.cornerRadius = 12
                  stopbutton.layer.borderWidth = 1
                  stopbutton.layer.borderColor = UIColor.white.cgColor
//               stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
                  
                  
                  stopbutton.translatesAutoresizingMaskIntoConstraints = false
                  
               NSLayoutConstraint.activate([
                  stopbutton.widthAnchor.constraint(equalToConstant: 150),
                  stopbutton.heightAnchor.constraint(equalToConstant: 50)
                  ])
            
            
            }
    }
        
    
    
   

它是这样的:

但它应该是这样的:

这是我在 StackView 上时控制台中出现的内容 VC:

我不知道这意味着什么,也不知道我应该怎么做才能解决这个问题

我不明白 StackViews...我看了很多 yt 教程,但它们都是一样的,对我没有帮助。我最大的问题是StackView的分布:我不知道区别在哪里

第一个提示:忘记对堆栈视图使用 .fillProportionally。它几乎从未被使用过……当它被使用时,它的使用是出于非常特殊的原因。

第二个提示:在开发过程中,为您的 UI 元素提供对比背景色,以便在 运行 时轻松查看帧。

第三个提示:使用 leadingLowerCase 作为变量和函数名称...使用 LeadingUpperCase 作为 class 名称。

第四个提示:将相似的代码组合在一起 - 例如设置视图属性、设置约束等 - 并包含逻辑注释,以便更容易理解代码的作用。

看看这个:

class PushUpViewController: UIViewController {
    
    let stackView = UIStackView()
    let secondStackView = UIStackView()
    let pushUpButton = UIButton()
    let breakButton = UIButton()
    let stopbutton = UIButton()
    let timeLabel = UILabel()
    
    var count: Int = 0
    var counter: Float = 0.0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        setUpStackView()
    }
    
    func setUpStackView() {
        
        // SetUp StackView:
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fill

        // SetUp timeLabel
        timeLabel.textAlignment = .center
        timeLabel.text = "\(counter)"
        timeLabel.textColor = .black
        timeLabel.font = .boldSystemFont(ofSize: 30)

        // SetUp pushUpButton:
        pushUpButton.backgroundColor = .white
        pushUpButton.setTitle("\(count)", for: .normal)
        pushUpButton.setTitleColor(.systemGray, for: .normal)
        pushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
        
        // SetUp secondStackView
        secondStackView.axis = .horizontal
        secondStackView.alignment = .fill
        secondStackView.distribution = .fillEqually
        secondStackView.spacing = 20
        
        //SetUp breakButton
        breakButton.backgroundColor = .lightGray
        breakButton.setTitle("Break", for: .normal)
        breakButton.setTitle("Start", for: .selected)
        breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
        breakButton.setTitleColor(.white, for: .normal)
        breakButton.layer.cornerRadius = 12
        breakButton.layer.borderWidth = 1
        breakButton.layer.borderColor = UIColor.white.cgColor
        
        // SetUp stopButton:
        stopbutton.backgroundColor = .systemRed
        stopbutton.setTitle("Stop", for: .normal)
        stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
        stopbutton.setTitleColor(.white, for: .normal)
        stopbutton.layer.cornerRadius = 12
        stopbutton.layer.borderWidth = 1
        stopbutton.layer.borderColor = UIColor.white.cgColor

        // add buttons to horizontal second stack view
        secondStackView.addArrangedSubview(breakButton)
        secondStackView.addArrangedSubview(stopbutton)

        // if we want the center PushUpButton to be 300 x 150
        //  and centered vertically
        //  we need to embed it in a clear view
        let holderView = UIView()
        
        // add PushUpButton to holderView
        holderView.addSubview(pushUpButton)

        // views added as arrangedSubviews of a stack view automatically get
        //  .translatesAutoresizingMaskIntoConstraints = false
        // but, because we're adding the PushUpButton as a subview
        //  of holderView, we need to set it here
        pushUpButton.translatesAutoresizingMaskIntoConstraints = false
        

        // add views to stack view
        stackView.addArrangedSubview(timeLabel)
        stackView.addArrangedSubview(holderView)
        stackView.addArrangedSubview(secondStackView)

        // add stackView to view
        view.addSubview(stackView)
        
        // SetUp StackView Constraints:
        //stackView.pin(to: view)
        
        // respect safe-area
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            // constrain stackview to full view (safe-area)
            
            // to bottom with Zero extra space
            stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),

            // to top with 20-pts "padding"
            stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            
            // and 8-pts "padding" on each side
            stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
            stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
            
            // pushUpButton should be 300x150
            pushUpButton.widthAnchor.constraint(equalToConstant: 300.0),
            pushUpButton.heightAnchor.constraint(equalToConstant: 150.0),
            
            // pushUpButton should be centered in holderView
            pushUpButton.centerXAnchor.constraint(equalTo: holderView.centerXAnchor),
            pushUpButton.centerYAnchor.constraint(equalTo: holderView.centerYAnchor),
            
            // bottom buttons should have Height: 50
            secondStackView.heightAnchor.constraint(equalToConstant: 50.0),
            
        ])

        // break and stop button actions
        //breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
        //stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)

        // during development, so we can see the layout easily
        //holderView.backgroundColor = .yellow
        //PushUpButton.backgroundColor = .green
        //TimeLabel.backgroundColor = .cyan
        
    }
}

iPhone11 的结果:

于 iPhone 8:

并在开发过程中提供背景颜色帮助:

附加提示:

学习自动布局(尤其是堆栈视图)时,请在 Storyboard / Interface Builder 中处理您的布局。您可以立即看到它的外观以及更改值/属性时会发生什么。您还可以更改 View as: 以立即查看它在不同设备/屏幕尺寸上的外观。如果您想将所有内容都保留在代码中,一旦您的布局看起来像您想要的那样,然后在代码中复制这些约束和设置。