iOS
UIScrollView AutoLayout
Sök…
ScrollableController
När du använder Autolayout med en UIScrollView
ändrar den INTE korrekt på beroende på storleken på dess innehåll eller undervyer.
För att få en UIScrollView
att automatiskt bläddra när dess innehåll blir för stort för att passa i det synliga området, måste vi lägga till en ContentView
och några begränsningar som gör att UIScrollView
kan bestämma storleken på innehållet och dess bredd och höjd i dess överordnade se.
import Foundation
import UIKit
class ScrollableController : UIViewController {
private var scrollView: UIScrollView!
private var contentView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//Setup
self.initControls()
self.setTheme()
self.layoutScrollView()
self.layoutContentView()
//Add child views
self.addChildViews()
}
func initControls() {
self.scrollView = UIScrollView()
self.contentView = UIView()
}
func setTheme() {
self.scrollView.backgroundColor = UIColor.blue()
self.contentView.backgroundColor = UIColor.orange()
}
func layoutScrollView() {
self.view.addSubview(self.scrollView)
let views: NSDictionary = ["scrollView": self.scrollView]
var constraints = Array<String>()
//Constrain the scrollView to our controller's self.view.
constraints.append("H:|-0-[scrollView]-0-|")
constraints.append("V:|-0-[scrollView]-0-|")
for constraint in constraints {
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views as! [String : AnyObject]))
}
self.scrollView.translatesAutoresizingMaskIntoConstraints = false
}
func layoutContentView() {
self.scrollView.addSubview(self.contentView)
let views: NSDictionary = ["contentView": self.contentView, "view": self.view]
var constraints = Array<String>()
//Constrain the contentView to the scrollView.
constraints.append("H:|-0-[contentView]-0-|")
constraints.append("V:|-0-[contentView]-0-|")
for constraint in constraints {
self.scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views as! [String : AnyObject]))
}
//Disable Horizontal Scrolling by making the contentView EqualWidth with our controller's self.view (ScrollView's parentView).
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[contentView(==view)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views as! [String : AnyObject]))
self.contentView.translatesAutoresizingMaskIntoConstraints = false
}
func addChildViews() {
//Init
let greenView = UIView()
let whiteView = UIView()
//Theme
greenView.backgroundColor = UIColor.green()
whiteView.backgroundColor = UIColor.orange()
//Layout -- Child views are added to the 'ContentView'
self.contentView.addSubview(greenView)
self.contentView.addSubview(whiteView)
let views: NSDictionary = ["greenView": greenView, "whiteView": whiteView];
var constraints = Array<String>()
//Constrain the greenView to the contentView with a height of 400 and 15 spacing all around.
constraints.append("H:|-15-[greenView]-15-|")
constraints.append("V:|-15-[greenView(400)]")
//Constrain the whiteView below the greenView with 15 spacing all around and a height of 500.
constraints.append("H:|-15-[whiteView]-15-|")
constraints.append("V:[greenView]-15-[whiteView(500)]-15-|")
for constraint in constraints {
self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views as! [String : AnyObject]))
}
greenView.translatesAutoresizingMaskIntoConstraints = false
whiteView.translatesAutoresizingMaskIntoConstraints = false
}
}
Nu kan vi se att greenView (400 höjd) + whiteView (500 höjd) är större än vår skärm. Detta kommer att få ScrollViews innehållsstorlek att växa så att det passar BÅDE vyer, vilket gör att den kan rulla vertikalt.
Vi inaktiverade horisontell rullning med EqualWidth
begränsningen på contentView
och self.view
UIScrollView dynamiskt innehållsstorlek via Storyboard
När du använder rullvyer i storyboard är det bättre att beräkna innehållsstorlek enligt antalet visningar som finns i rullvisningen snarare än att ge innehållsstorlek programmatiskt med statiskt värde.
Här är stegen för att få innehållsstorlek dynamiskt.
Steg 1 :
Lägg till Scrollview för att visa i storyboard och lägg till begränsningar som leder till, efter, ovan och ned (Alla värden är noll).
Steg 2 :
Lägg inte till direktvyer som du behöver på direkt rullningsvy, lägg först en vy till rullvisningen (det är vår innehållsvy för alla UI-element). Lägg till begränsningar nedan för denna vy.
Ledande, släpande, övre och undre begränsningar (Alla värden är noll).
Lägg till lika höjd, lika bredd som huvudvy (dvs. som innehåller rullvisning). För lika höjd ställ in prioritet till låg. (Detta är det viktiga steget för att ställa in innehållsstorlek).
Höjden på den här innehållsvynen kommer att bero på antalet vyer som läggs till i vyn. låt oss säga att om du lägger till den senaste vyn är en etikett och hans Y-position är 420 och höjden är 20 så kommer din innehållsvy att vara 440.
Steg 3: Lägg till begränsningar i alla vyer som du har lagt till i innehållsvyn enligt dina krav.