带有自动布局的程序化 UIScrollview

Programmatic UIScrollview with Autolayout(带有自动布局的程序化 UIScrollview)
本文介绍了带有自动布局的程序化 UIScrollview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读了苹果网站上的技术说明并阅读了 matt neuburg 关于使用 Autolayout 保持 UIScrollview 进行 iOS 11 编程的书之后,我无法完全理解它是如何工作的概念.

After reading the technical notes on apple's website and reading matt neuburg's book on programming iOS 11 with a UIScrollview held in place with Autolayout, I have not been able to fully understand the concept of how it all works.

基本上我想要的是一个 Scrollview,它会有一个子视图 ChildView,而这个子视图有一个 Textview.

Basically what I want to have is a Scrollview that would have a child view ChildView where this child view then has a Textview.

下面我附上了我试图以程序化无笔尖,无情节提要实现的目标的模型.

Below I have attached the mockup of what I am trying to achieve Programmatically no-nibs, no storyboards.

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

and as for the code, This is what I usually come up with:

代码

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 以允许子视图成为这个更大视图的子视图,该更大的视图将滚动视图作为其父视图.

Please Note: for the ContentView, I normally define constraints to anchor the edges inside the scrollview but not in this case with Autolayout and the fact that I want it to scroll vertically upwards when the keyboard becomesFirstResponder. Another way I came up with this to try to work is to create a UIView that spans larger than the Scrollview to allow the child view to be a subview of this larger view that has the scroll view as its parent.

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

My Problem: How can I achieve this from here onwards? Any suggestions? I have been giving it a thought to something like this: (ContentView would be the larger view that will allow this to be scrollable, and the child view would be the 3rd child view in the hierarchy)

推荐答案

  1. 你不需要创建一个虚假的内容视图,你可以直接将子视图添加到滚动视图(我更喜欢).Apple 不建议创建一个,他们只建议您可以.

  1. You don't need to create a faux content view, you can add subviews directly to the scroll view (which I prefer). Apple does not recommend creating one, they only suggest that you can.

滚动视图的子视图不应依赖滚动视图来确定它们的大小,只依赖它们的位置.

Subviews of the scroll view shall not rely on the scroll view to determine their sizes, only their positions.

您的约束必须定义最左侧、最右侧、最顶部和最底部边缘,以便自动布局为您创建内容视图.

Your constraints must define the left-most, right-most, top-most, and bottom-most edges in order for auto layout to create the content view for you.

当你创建一个滚动视图时,你可以给它的框架赋予控制器视图的边界:

When you create a scroll view, you may give its frame the bounds of the controller's view:

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

然后,您必须通过将其子视图锚定到滚动视图的边缘来设置内容视图的边界.要实现仅垂直滚动,您的最顶层视图必须锚定到滚动视图的顶部,并且锚定到前缘和后缘的任何子视图都不得超过滚动视图的宽度.

You must then set the boundaries of the content view by anchoring its subviews to the edges of the scroll view. To achieve vertical-only scrolling, your top-most view must be anchored to the top of the scroll view and none of the subviews anchored to the leading and trailing edges must exceed the width of the scroll view.

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 的高度,但它不会滚动,因为没有任何东西被锚定到滚动视图的底部.因此,请在最底部的视图中执行此操作.

Notice the topMostView does not rely on the scroll view to determine its size, only its position. The content in your scroll view now has a height of 1000 but it won't scroll because nothing is anchored to the bottom of the scroll view. Therefore, do that in your bottom-most view.

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

最后一个锚点可能看起来很奇怪,因为您将 1,000 点高的视图锚定到您刚刚锚定到绝对小于 1,000 的视图底部的锚点 点高.但这就是苹果希望你这样做的方式.通过这样做,您不需要创建内容视图,自动布局会为您完成.

The last anchor may seem odd because you're anchoring a view that is 1,000 points tall to an anchor that you just anchored to the bottom of the view which is definitely less than 1,000 points tall. But this is how Apple wants you to do it. By doing this, you do not need to create a content view, auto layout does it for you.

定义边缘约束";(最左、最右、最上、最下)超出了滚动视图.当您创建自定义 UITableViewCell 时,例如,使用自动布局,定义四个边缘约束(即最顶层的子视图锚定到单元格的顶部 topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true,最底部的子视图到单元格底部bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true等)是您创建自定尺寸单元的方式.实际上,定义边缘约束是您创建任何自定尺寸视图的方式.

Defining the "edge constraints" (left-most, right-most, top-most, bottom-most) goes beyond scroll views. When you create a custom UITableViewCell, for example, using auto layout, defining the four edge constraints (i.e. where the top-most subview is anchored to the top of the cell topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true, the bottom-most subview to the bottom of the cell bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true, etc.) is how you create self-sizing cells. Defining the edge constraints is how you create any self-sizing view, really.

这篇关于带有自动布局的程序化 UIScrollview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Why local notification is not firing for UNCalendarNotificationTrigger(为什么没有为UNCalendarNotificationTrigger触发本地通知)
iOS VoiceOver functionality changes with Bundle Identifier(IOS画外音功能随捆绑包标识符而变化)
tabbar middle tab out of tabbar corner(选项卡栏中间的选项卡角外)
Pushing UIViewController above UITabBar(将UIView控制器推送到UITabBar上方)
Dropbox Files.download does not start when number of files in folder is gt; 1000(当文件夹中的文件数为1000时,Dropbox Files.Download不会启动)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)