StackView
There are many layouts that can be combined with landscape and vertical layouts, in which case you can use UIStackView to simplify the creation of a layout.
Suppose we want to lay out three labels horizontally, with margins between them, like this:
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) self.window! .rootViewController = Page() self.window? .makeKeyAndVisible() return true } } class Page: UIViewController { override func viewDidLoad() { super.viewDidLoad() let label1 = UILabel() label1.backgroundColor = UIColor.blue label1.text = "Hallo" let label2 = UILabel() label2.backgroundColor = UIColor.yellow label2.text = "Hi" let label3 = UILabel() label3.backgroundColor = UIColor.red label3.text = "Hello" let stackView = UIStackView() stackView.axis = .horizontal stackView.spacing = 6 stackView.addArrangedSubview(label1) stackView.addArrangedSubview(label2) stackView.addArrangedSubview(label3) stackView.translatesAutoresizingMaskIntoConstraints = false; self.view.addSubview(stackView) } }Copy the code
Once a label instance is created and initialized, it can be thrown directly into the UIStackView container, which passes the “axial” attribute
.axis = .horizontalCopy the code
Represented as a horizontal layout, the added views are arranged horizontally one by one. This property can also be set to vertical to indicate vertical arrangement. And by attributes:
.spacing = 6Copy the code
The distance between views is 6. In particular, if you want UIStackView to manage the layout of the added control, you must use addArrangedSubview instead of the addSubview method. With UIStackView layout, you don’t need to specify the position of the view, and often you don’t need to specify the size, because UIKit automatically calculates the position and size for you.
Use nested
As long as StackView’s horizontal and vertical layouts can be nested, many layout problems can be solved. For example, put three horizontal StackViews together in a vertical container. Suppose we want to do a case where we have a vertical layout, a landscape layout and a label in the layout, and two labels in the landscape layout. The hierarchy looks like this:
verticalStackView
--horizontalStackView
----label
----label
--labelCopy the code
The code is as follows:
import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.window = UIWindow(frame: UIScreen.main.bounds) self.window! .rootViewController = Page() self.window? .makeKeyAndVisible() return true } } class Page: UIViewController { override func viewDidLoad() { super.viewDidLoad() var verticalStackView: UIStackView! verticalStackView = UIStackView() verticalStackView.axis = .vertical verticalStackView.distribution = .fillEqually verticalStackView.spacing = 10 let blue = UILabel() blue.backgroundColor = .blue let green = UILabel() green.backgroundColor = .green let horizontalStackView = UIStackView() horizontalStackView.axis = .horizontal horizontalStackView.distribution = .fillEqually horizontalStackView.spacing = 10 horizontalStackView.addArrangedSubview(blue) horizontalStackView.addArrangedSubview(green) let red = UILabel() red.backgroundColor = .red red.heightAnchor.constraint(equalToConstant: 34).isActive = true verticalStackView.addArrangedSubview(horizontalStackView) verticalStackView.addArrangedSubview(red) verticalStackView.frame = view.bounds view.addSubview(verticalStackView) } }Copy the code
That is, one StackView can be combined with another StackView to create common and complex layouts. Also, the property distribution uses a new value:
verticalStackView.distribution = .fillEquallyCopy the code
Indicates that views within StackView fill all space equally. This property can also take on the following values:
- Fill makes one of the subviews take up the maximum space and the other views the natural size.
- FillEqually adjusts each view equally to take up the full space.
- Each view is stretched proportionally in order to fill the space. Let’s say one view is 100, another view is 200, and so on and so on, maybe one view becomes 150, and the other one becomes 300
- EqualSpacing adjusts the spacing between views rather than stretching them to fill space
- Equalpress positions strive to have equal space between the center points of each subview