Swift iOS:AutoLayout 快速介紹

AutoLayout

典型的,加入一個子視圖的作法就是建立實例,指定位置,而後把它加入到視圖裏面來。在指定位置的代碼處,通常就是設置frame屬性便可,就像這樣:javascript

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{
        var vw : UIView!
        override func viewDidLoad() {
            super.viewDidLoad()
            vw = UIView()
            vw.backgroundColor = .red
            vw.frame = CGRect(x: 5, y: 5, width: 50, height: 50)
            view.addSubview(vw)
        }
    }複製代碼

代碼把一個邊長爲50的正方形加入到x: 5, y: 5的位置上,位置相對於它的父視圖的左上腳點。若是咱們的相對點變化了,好比說但願把這個正方形以自身的右下腳點爲慘遭,放到相對於父視圖的右下腳點的的-5,-5的位置上的話,會產生些問題:java

  1. 正方形的左上角的x和y的值就得本身計算
  2. 當手機旋轉時,屏幕的橫向長度和縱向長度就變了,所以x和y的值也得本身從新計算

解決此問題的要點在於,App只是聲明本身的位置關係,具體的座標有UIKit來計算。如今UIKit提供的AutoLayout技術就能夠解決此問題。app

就以此問題爲例,能夠去掉:ide

vw.frame = CGRect(x: 5, y: 5, width: 50, height: 50)複製代碼

改爲以下的約束:函數

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{
        var vw : UIView!
        override func viewDidLoad() {
            super.viewDidLoad()
            vw = UIView()
            vw.backgroundColor = .red
            view.addSubview(vw)
            vw.translatesAutoresizingMaskIntoConstraints = false
            let horizontalConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -5)
            let verticalConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: -5)
            let widthConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 50)
            let heightConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 50)
            view.addConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])

        }
    }複製代碼

首先必須設置此視圖的屬性:佈局

vw.translatesAutoresizingMaskIntoConstraints = false複製代碼

這樣AutoLayout才能生效。隨後建立的第一約束:spa

let horizontalConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -5)複製代碼

看起來有些複雜,可是若是知道一個公式就更容易讀懂此代碼。NSLayoutConstraint用來建立閱讀,其函數參數標籤有:code

  1. item 要定位的視圖對象
  2. attribute 要定位的視圖對象的屬性
  3. relatedBy 相對關係,也就是公式內的操做符號,最經常使用的就是等於,可是也可使用大於小於等操做符號
  4. toItem 用來對定位點的視圖對象
  5. attribute 用來對定位點的視圖對象的屬性
  6. multiplier 係數
  7. constant 常數

公式由此標籤指定以下:對象

item.attribute relatedBy toItem.attribute*multiplier + constant複製代碼

標籤relatedBy指定的是一個操做符號,此處爲「=」,所以此公式簡化爲:ip

item.attribute = toItem.attribute*multiplier + constant複製代碼

再次的把標籤帶入參數值,就是這樣:

vw.right = view.right*1 - 5複製代碼

讀出來的意思就是:

視圖vw的右邊x值約束爲視圖view的右邊x值乘以1再減去5複製代碼

因而能夠類推第二個約束爲正方形的下邊y值和父視圖的下邊y值的約束定義:

視圖vw的下邊y值約束爲視圖view的下邊y值乘以1再減去5複製代碼

此案例中,正方形的寬度則只是一個常數值,並不須要相對於任何視圖的任何屬性,所以建立類NSLayoutConstraint時,公式中:

item.attribute relatedBy toItem.attribute*multiplier + constant複製代碼

的toItem.attribute*multiplier總體是無心義的,而簡化爲:

item.attribute = constant複製代碼

這也就是代碼:

let widthConstraint = NSLayoutConstraint(item: vw, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 50)複製代碼

標籤toItem爲nil, 標籤attribute爲NSLayoutAttribute.notAnAttribute的含義。一樣的,正方形的高度也是如此分析。

使用自動佈局,一個視圖的位置的參照物再也不僅僅是父視圖的左上腳點,而是變得豐富多彩,依據不一樣的狀況有不一樣的選擇:

  1. 指定視圖的中心點和父視圖重合
  2. 指定一個視圖和它的兄弟視圖緊靠
  3. 靠左靠右靠上靠下

如此等等。所以以前的指定xy值的作法,就稱爲自動佈局方法的一個特殊案例。

相關文章
相關標籤/搜索