Programmatic UIScrollview with Autolayout(带有自动布局的程序化 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)
推荐答案
你不需要创建一个虚假的内容视图,你可以直接将子视图添加到滚动视图(我更喜欢).Apple 不建议创建一个,他们只建议您可以.
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:带有自动布局的程序化 UIScrollview
基础教程推荐
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01