scrollView 在 stackView 中不起作用,如何以编程方式滚动 stackView

scrollView not working in stackView, How to programmatically scroll a stackView

我添加到ScrollView stackView中,并在stackView中添加了一些标签,但是没有滚动,为什么没有滚动?我尝试在 stackView 中添加 scrollView,它没有用,请帮助我,下面附上代码

class ViewController: UIViewController {

    let scrollView = UIScrollView()

    let formulas = ["", "", "","","", "", "",""]
    
    let formulasStackView: UIStackView = {
        let stackView = UIStackView()
        stackView.backgroundColor = #colorLiteral(red: 0.2587976158, green: 0.2588401437, blue: 0.258788228, alpha: 1)
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fillEqually
        stackView.spacing = 5
        return stackView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupScrollView()
        addFormulas()
    }

    func setupScrollView(){
           scrollView.translatesAutoresizingMaskIntoConstraints = false
            formulasStackView.translatesAutoresizingMaskIntoConstraints = false
           view.addSubview(scrollView)
         
           
           scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
           scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
           scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
           scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        
        scrollView.addSubview(formulasStackView)
    
        formulasStackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
        formulasStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
        formulasStackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        
       }

    func addFormulas() {
        for index in 0..<formulas.count {
            addFormulaView()
        }
    }

    func addFormulaView() {
        let formulaView: UIView = {
            let view = UIView()
            view.backgroundColor = #colorLiteral(red: 0.1882152259, green: 0.1882481873, blue: 0.1882079244, alpha: 1)
            view.layer.cornerRadius = 6
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
        formulasStackView.addArrangedSubview(formulaView)
        
        formulaView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        formulaView.leadingAnchor.constraint(equalTo: formulasStackView.leadingAnchor, constant: 5).isActive = true
        formulaView.trailingAnchor.constraint(equalTo: formulasStackView.trailingAnchor, constant: -5).isActive = true
        formulaView.translatesAutoresizingMaskIntoConstraints = false
    }
}

两件事...

首先,没有直接关系,但最好将元素限制在视图的安全区域

其次,我们要将滚动视图的 子视图 的定位(顶部/前导/尾随/底部)约束到滚动视图的 内容布局指南(在这种情况下,唯一的子视图将是您的堆栈视图——您的“公式视图”将是堆栈视图的子视图)。将大小(在本例中为堆栈视图的宽度)限制为滚动视图的框架布局指南

第三,如果 UI 元素是其 superView 的宽度,最好使用 Leading 和 Trailing 约束,而不是 Width 和 CenterX 约束。

所以,这是您的 class 并进行了一些更改 -- 查看代码中的注释:

class ViewController: UIViewController {
    
    let scrollView = UIScrollView()
    
    let formulas = ["", "", "","","", "", "",""]
    
    let formulasStackView: UIStackView = {
        let stackView = UIStackView()
        stackView.backgroundColor = #colorLiteral(red: 0.2587976158, green: 0.2588401437, blue: 0.258788228, alpha: 1)
        stackView.axis = .vertical
        stackView.alignment = .fill
        stackView.distribution = .fillEqually
        stackView.spacing = 5
        return stackView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupScrollView()
        addFormulas()
    }
    
    func setupScrollView(){
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        formulasStackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(scrollView)
        
        // always a good idea to respect the safe-area
        
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([

            scrollView.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
            scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
            scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
            scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),

            // use Leading and Trailing anchors instead
            //scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            //scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
            
        ])
        
        scrollView.addSubview(formulasStackView)
        
        let cg = scrollView.contentLayoutGuide
        let fg = scrollView.frameLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // let's "inset" the stack view with 5-pts "padding" on all four sides
            formulasStackView.topAnchor.constraint(equalTo: cg.topAnchor, constant: 5.0),
            formulasStackView.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 5.0),
            formulasStackView.trailingAnchor.constraint(equalTo: cg.trailingAnchor, constant: -5.0),
            formulasStackView.bottomAnchor.constraint(equalTo: cg.bottomAnchor, constant: -5.0),
            
            // we have 5-pts on each side of the stack view, so
            //  constrain its width minus 10-pts
            formulasStackView.widthAnchor.constraint(equalTo: fg.widthAnchor, constant: -10.0),
        ])
        
        // these are wrong
        //formulasStackView.centerXAnchor.constraint(equalTo: scrollView.contentLayoutGuide.centerXAnchor).isActive = true
        //formulasStackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
        //formulasStackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        
    }
    
    func addFormulas() {
        for index in 0..<formulas.count {
            addFormulaView()
        }
    }
    
    func addFormulaView() {
        let formulaView: UIView = {
            let view = UIView()
            view.backgroundColor = #colorLiteral(red: 0.1882152259, green: 0.1882481873, blue: 0.1882079244, alpha: 1)
            view.layer.cornerRadius = 6
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
        formulasStackView.addArrangedSubview(formulaView)

        // views added as arranged subviews automatically get this set to false
        //  so not necessary
        //formulaView.translatesAutoresizingMaskIntoConstraints = false

        // all we need to do is constrain the height
        formulaView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        
        // do NOT add either of these constraints
        //formulaView.leadingAnchor.constraint(equalTo: formulasStackView.leadingAnchor, constant: 5).isActive = true
        //formulaView.trailingAnchor.constraint(equalTo: formulasStackView.trailingAnchor, constant: -5).isActive = true
    }
}