問題描述
在閱讀了蘋果網站上的技術說明并閱讀了 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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!