Autolayout的程序化UIScrollview

时间:2018-01-11 22:26:08

标签: ios swift uiscrollview autolayout

在阅读了Apple网站上的技术说明并阅读了有关使用Autolayout的UIScrollview的iOS 11编程的matt neuburg的书之后,我无法完全理解这一切的概念。

基本上我想要的是一个 Scrollview ,它会有一个子视图 ChildView ,其中这个子视图的 Textview 。< / p>

下面我附上了我想要实现的模型编程 no-nibs,没有故事板。

enter image description here

至于代码,这就是我通常提出的:

代码

let Scroller: UIScrollView = {
    let scroll = UIScrollView()
    scroll.translatesAutoresizingMaskIntoConstraints = false
    scroll.backgroundColor = UIColor.alizarinColor()
    return scroll
}()

// Content view

let ContentView : UIView = {

    let content = UIView()
    content.translatesAutoresizingMaskIntoConstraints = false
    content.backgroundColor = UIColor.blue
    return content
}()

override func viewDidLoad() {

    super.viewDidLoad()

    self.view.addSubview(Scroller)

    // Auto layout
    Scroller.leftAnchor.constraint(equalTo: view.leftAnchor, constant:0).isActive = true
    Scroller.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
    Scroller.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
    Scroller.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true

    Scroller.addSubview(ContentView)
    // Undefined Content view 
}
对于 ContentView

请注意,我通常会定义约束来锚定滚动视图中的边缘,但在这种情况下不支持Autolayout以及我想要它的事实键盘becomesFirstResponder时垂直向上滚动。我想出来的另一种方法是创建一个比Scrollview更大的UIView,以允许子视图成为这个以滚动视图为父视图的大视图的子视图。

我的问题:如何从此开始实现此目标?有什么建议? 我一直在考虑这样的事情:( ContentView将是允许它可滚动的较大视图,子视图将是层次结构中的第3个子视图)

enter image description here

2 个答案:

答案 0 :(得分:32)

我仔细阅读了Apple关于UIScrollView如何使用自动布局的文档。

  1. 首先,您不需要创建虚假内容视图,您可以直接将子视图添加到滚动视图(我更喜欢这个,因为我认为虚假内容视图是无关紧要的和不必要的对象)。 Apple不建议创建一个,他们只建议你可以。

  2. 其次,滚动视图的子视图不应依赖滚动视图来确定其大小,只能确定其位置

  3. 第三,您的约束必须定义最左边,最右边,最顶边和最底边,以便自动布局为您创建内容视图。这个规则起初可能看起来有悖常理,但苹果希望你如何构建滚动视图。

  4. 具体来说,当您创建滚动视图时,您可以为其框架指定控制器视图的边界:

    scrollView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(scrollView)
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    

    然后,您必须通过将其子视图锚定到滚动视图的边缘来设置内容视图的边界。因此,您的最顶层视图必须锚定在滚动视图的顶部,其宽度不能超过滚动视图的宽度(这是视图的宽度)(如果您的目标是垂直滚动< / em>的)。

    topMostView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(topMostView)
    topMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    topMostView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    topMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    topMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true
    

    请注意topMostView不依赖于滚动视图来确定其大小(仅限其位置) - 这很重要。

    滚动视图中的内容现在的高度为1000,但它不会滚动,因为没有任何内容锚定在滚动视图的底部。因此,请在最底层的视图中执行此操作。

    bottomMostView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(bottomMostView)
    bottomMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    bottomMostView.topAnchor.constraint(equalTo: topMostView.bottomAnchor).isActive = true
    bottomMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    bottomMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true
    
    bottomMostView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    

    最后一个锚可能看起来很奇怪,因为你将1000点高的视图锚定到一个锚点,你刚刚锚定到视图的底部,这个点肯定小于1000点高。但这就是Apple希望你这样做的方式。这样,您不需要创建内容视图,自动布局就可以为您完成。当然,您仍可以正常从滚动视图的属性访问内容视图的维度。

    顺便说一句,定义“边缘约束”(最左边,最右边,最顶部,最底部)的这个原则超出了滚动视图。使用自动布局创建自定义UITableViewCell时,定义四个边缘约束(即最顶部子视图锚定到单元格顶部的位置topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true,最底部的子视图位于底部单元格bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true等)是您创建自定义单元格的方式。这就是你如何创建自我调整的东西,真的,如视图,控件等。

答案 1 :(得分:5)

当你创建一个scrollView时,apple建议在其中放入一个contentView,并将该contentView赋予viewController视图的宽度,并将它的顶部,底部,前导,尾随约束固定到scrollview,然后根据需要从顶部到底部放置项目,并将最底部的项目固定到scollview的contentView底部,这样滚动视图可以渲染它的高度,这个底部约束可以按照您的喜好并根据它scrollview将继续滚动直到完成它