在将 View 添加到我的应用程序之前,我已经创建了一个小型演示游乐场来使其工作。

我有一个滚动 View ,它将包含许多水平滚动的按钮。我知道这些按钮需要进入滚动 View 中的容器 View ,并且也创建了它。我最初使用自动布局约束来创建所有这些,但现在尝试使用常量来确保内容 View 大于滚动 View 。但是,按钮仍然不会滚动......我错过了什么吗?滚动 View 不适用于自动布局吗?

我也在我的 iPad 上以编程方式执行所有这些操作,因此不幸的是,使用界面构建器的解决方案不是一种选择...

这是完整的代码:

import UIKit
import PlaygroundSupport

class FilterViewController: UIViewController {
    var filterView: UIView!
    var scrollView: UIScrollView!
    var containerView: UIView!

    override func loadView() {
        filterView = UIView()
        view = filterView
        view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)

        scrollView = UIScrollView()
        scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo:view.topAnchor, constant:40).isActive = true
        scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
        scrollView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive = true
        scrollView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        scrollView.isScrollEnabled = true

        containerView = UIView()
        containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
        scrollView.addSubview(containerView)
        containerView.frame = CGRect(x: 0, y: 0, width: 1080, height: 200)
    }

    class Buttons{
        let button = UIButton()
        init (titleText : String){
            button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
            button.setTitle(titleText, for: .normal)
            button.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let b1 = Buttons(titleText: "one")
        let b2 = Buttons(titleText: "two")
        let b3 = Buttons(titleText: "three")
        let b4 = Buttons(titleText: "four")
        let b5 = Buttons(titleText: "five")
        let buttonArray = [b1,b2,b3,b4,b5]
        var startPoint : CGFloat = 0.0
        for btn in buttonArray {
            let theBtn = btn.button
            containerView.addSubview(theBtn)
            theBtn.frame = CGRect(x: startPoint, y: 0, width: 200, height: 200)
            startPoint += 220
        }

    }
}

let filterViewController = FilterViewController()
PlaygroundPage.current.liveView = filterViewController

谢谢瓦卡瓦玛!
这是具有所有自动布局约束的完整(现在工作)迷你项目:
import UIKit
import PlaygroundSupport

class FilterViewController: UIViewController {
    var filterView: UIView!
    var scrollView: UIScrollView!
    var containerView: UIView!

    override func loadView() {
        filterView = UIView()
        view = filterView
        view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)

        scrollView = UIScrollView()
        scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.topAnchor.constraint(equalTo:view.topAnchor, constant:40).isActive = true
        scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
        scrollView.widthAnchor.constraint(equalTo:view.widthAnchor).isActive = true
        scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25).isActive = true
        scrollView.isScrollEnabled = true

        containerView = UIView()
        containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
        scrollView.addSubview(containerView)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.topAnchor.constraint(equalTo:scrollView.topAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo:scrollView.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo:scrollView.trailingAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo:scrollView.bottomAnchor).isActive = true
        containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true



    }

    class Buttons{
        let button = UIButton()
        init (titleText : String){
            button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
            button.setTitle(titleText, for: .normal)
            //button.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let b1 = Buttons(titleText: "one")
        let b2 = Buttons(titleText: "two")
        let b3 = Buttons(titleText: "three")
        let b4 = Buttons(titleText: "four")
        let b5 = Buttons(titleText: "five")
        let buttonArray = [b1,b2,b3,b4,b5]
        var startPoint = containerView.leadingAnchor
        for btn in buttonArray {
            let theBtn = btn.button
            containerView.addSubview(theBtn)
            theBtn.translatesAutoresizingMaskIntoConstraints = false
            theBtn.leadingAnchor.constraint(equalTo:startPoint, constant:20).isActive = true
            theBtn.topAnchor.constraint(equalTo:containerView.topAnchor).isActive = true
            theBtn.bottomAnchor.constraint(equalTo:containerView.bottomAnchor).isActive = true
            theBtn.widthAnchor.constraint(equalTo: theBtn.heightAnchor).isActive = true
            startPoint = theBtn.trailingAnchor
            containerView.widthAnchor.constraint(equalTo: theBtn.widthAnchor, multiplier:CGFloat(buttonArray.count), constant: CGFloat(buttonArray.count * 20)).isActive = true
        }
    }
}

let filterViewController = FilterViewController()
PlaygroundPage.current.liveView = filterViewController

最佳答案

您可以使用自动布局来做到这一点。秘诀是将 containerView 的边缘限制为 scrollView 的边缘。这不直观,但约束 containerView 的边缘并没有设置大小,它只是确保 scrollView 的内容大小随着 containerView 的增长而增长。通过将 containerView 宽度的约束设置为一个大于 scrollView 宽度的常数,内容将水平滚动。

注意: 这样配置 scrollView 时,不设置 contentSizescrollViewcontentSize 将由自动布局为您计算,它等于 containerView 的大小。确保 containerView 的大小完全由约束指定是很重要的。

这是我为使其工作所做的更改:

containerView = UIView()
containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
scrollView.addSubview(containerView)
//containerView.frame = CGRect(x: 0, y: 0, width: 1080, height: 200)
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.topAnchor.constraint(equalTo:scrollView.topAnchor).isActive = true
containerView.leadingAnchor.constraint(equalTo:scrollView.leadingAnchor).isActive = true
containerView.trailingAnchor.constraint(equalTo:scrollView.trailingAnchor).isActive = true
containerView.bottomAnchor.constraint(equalTo:scrollView.bottomAnchor).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.widthAnchor.constraint(equalToConstant: 1080).isActive = true



要使其滚动, containerView 必须大于 scrollView 。您的错误是您设置了约束,使得 containerView 的宽度和高度与 scrollView 相同,这就是您的内容不滚动的原因。

如果您希望它水平滚动,则 containerView 的宽度必须大于 scrollView 的宽度。您可以通过以下两种方式之一执行此操作:
  • containerView 指定一个大于 scrollView 宽度的显式恒定宽度。

  • 从左到右链接 containerView 的 subview ,最左边的包含在 containerView 的前沿。完全指定 subview 的宽度,并在 subview 之间放置距离约束。最右边的 subview 必须与 containerView 的后缘有一个偏移量。通过这样做,自动布局可以计算 containerView 的宽度并设置 contentSizescrollView


  • 迷你项目:更新

    这是您的迷你项目的一个版本,它使用一系列受约束的 View 来定义 containerView 的宽度。关键是 forviewDidLoad() 循环之后的最终约束,它将最后一个按钮的 trailingAnchor(又名 startPoint )连接到 containerView 的 trailingAnchor。这完成了将 containerView 的前缘与 containerView 的后缘连接起来的约束和按钮链。有了这个,自动布局能够计算 containerView 的宽度并建立 contentSizescrollView
    import UIKit
    import PlaygroundSupport
    
    class FilterViewController: UIViewController {
        var filterView: UIView!
        var scrollView: UIScrollView!
        var containerView: UIView!
    
        override func loadView() {
            filterView = UIView()
            view = filterView
            view.backgroundColor = #colorLiteral(red: 0.909803926944733, green: 0.47843137383461, blue: 0.643137276172638, alpha: 1.0)
    
            scrollView = UIScrollView()
            scrollView.backgroundColor = #colorLiteral(red: 0.474509805440903, green: 0.839215695858002, blue: 0.976470589637756, alpha: 1.0)
            view.addSubview(scrollView)
            scrollView.translatesAutoresizingMaskIntoConstraints = false
            scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40).isActive = true
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
            scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
            scrollView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25).isActive = true
            scrollView.isScrollEnabled = true
    
            containerView = UIView()
            containerView.backgroundColor = #colorLiteral(red: 0.176470592617989, green: 0.498039215803146, blue: 0.756862759590149, alpha: 1.0)
            scrollView.addSubview(containerView)
            containerView.translatesAutoresizingMaskIntoConstraints = false
    
            // This is key:  connect all four edges of the containerView to
            // to the edges of the scrollView
            containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
            containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
            containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
            containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    
            // Making containerView and scrollView the same height means the
            // content will not scroll vertically
            containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
        }
    
        class Buttons {
            let button = UIButton()
            init(titleText: String) {
                button.backgroundColor = #colorLiteral(red: 0.976470589637756, green: 0.850980401039124, blue: 0.549019634723663, alpha: 1.0)
                button.setTitle(titleText, for: .normal)
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let b1 = Buttons(titleText: "one")
            let b2 = Buttons(titleText: "two")
            let b3 = Buttons(titleText: "three")
            let b4 = Buttons(titleText: "four")
            let b5 = Buttons(titleText: "five")
            let buttonArray = [b1, b2, b3, b4, b5]
            var startPoint = containerView.leadingAnchor
            for btn in buttonArray {
                let theBtn = btn.button
                containerView.addSubview(theBtn)
                theBtn.translatesAutoresizingMaskIntoConstraints = false
                theBtn.leadingAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
                theBtn.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
                theBtn.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
                theBtn.widthAnchor.constraint(equalTo: theBtn.heightAnchor).isActive = true
                startPoint = theBtn.trailingAnchor
            }
            // Complete the chain of constraints
            containerView.trailingAnchor.constraint(equalTo: startPoint, constant: 20).isActive = true
        }
    }
    
    let filterViewController = FilterViewController()
    PlaygroundPage.current.liveView = filterViewController
    

    关于ios - 我的带有自动布局约束的 Swift 4 UIScrollView 不滚动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51688114/

    10-11 16:14