AutoLayout - VFL

其實很早就像整理出一份VFL的總結出來,以爲有不少東西能夠寫,可是真正去總結的時候發現,VFL也並無不少東西,其實應該是在佈局的過程當中直接用VFL語句思考的過程比較難以造成,多數佈局問題實際上是在實際操做中才會有愈來愈深的體會,關鍵在用。可能有些詞不達意,很少說了,如下將VFL的基本表達列出。
 
AutoLayout,顧名思義,是自動佈局,自動佈局的實現有不少種,我以前在開發過程當中比較多用到的是VFL和Mansory;可是通常狀況下,不是很複雜的佈局控件會直接使用frame進行計算,因此事實上也不是整個項目都在使用VFL,並且不少時候VFL 也有其侷限性,好比我要設置一個比例的高度,就要本身寫NSLayoutConstraint,也挺複雜,而通常狀況下,我都會先實現UIView的分類,簡化對於frame進行操做的方法,這樣能夠直接獲取或者設置height,而不須要從view.frame...的一層層去取,因此若是在這種狀況下,會有一些佈局即便使用了VFL也並無簡化多少(也有多是我對VFL尚未精深到必定境界吧);可是不少複雜一些的佈局,VFL和Mansory的使用確實會節省不少時間。
 
一、VFL的語法含義:
               H:  ->  水平方向;
                V:  ->  豎直方向;
           [aaa]  ->  views參數中key值爲aaa的view控件;
                  |  ->  父視圖的邊界;
   >=,==,<=  ->  關係;
                  -  ->  間隔,當設置30的間隔時爲 -30- ,不設置時會顯示默認間隔;而當使用matrics來設置數值時,30這個數值也能夠直接使用matrics中設置的key值;
           @100  ->  優先級,優先級最高爲1000,數值越高約束的優先級越高;
 
二、VFL的示例解釋:
     H:|-10-[aView(60)]-40-[bView]-30-|   
               第一個"|"表示左邊距,"-10-"表示距左邊距10像素,"[aView(60)]"表示aView對應的控件寬度爲60,"-40-"表示aView和bView的間隔爲40,"-30-"則表示距離右邊距30,其中,bView並未設置寬度,會有已有條件剩餘的部分做爲寬度來顯示;
        事實上,在理解VFL的語句時,倒不妨就把語句當成屏幕,只不過把控件的水平方向的排布分離出來用一種格式化的方式表示而已。
 
     V:|[aView(>=60@900)]-50-[bView(>=400@899)]-30@901-|
               @後面的表示優先級,當多個條件有衝突時,會確保高優先級的條件;
 
 
三、使用步驟
           建立VFL語句  ->  建立約束(NSLayoutConstraint.constraintsWithVisualFormat)  ->  將約束添加到父視圖;
 
四、代碼示例:
 
        self.view.backgroundColor = UIColor.greenColor()
    
        let superView = UIView(frame: CGRect(x: 20, y: 100, width: 300, height: 400))
        superView.backgroundColor = UIColor.blueColor()
        self.view.addSubview(superView)
        
        let label_01 = UILabel()
        label_01.text = "label_01"
        label_01.backgroundColor = UIColor.redColor()
        superView.addSubview(label_01)
        
        let label_02 = UILabel()
        label_02.text = "label_02"
        label_02.backgroundColor = UIColor.grayColor()
        superView.addSubview(label_02)
        
        let label_03 = UILabel()
        label_03.text = "label_03"
        label_03.backgroundColor = UIColor.brownColor()
        superView.addSubview(label_03)
        
        let label_04 = UILabel()
        label_04.text = "label_04"
        label_04.backgroundColor = UIColor.cyanColor()
        superView.addSubview(label_04)

        
        label_01.translatesAutoresizingMaskIntoConstraints = false
        label_02.translatesAutoresizingMaskIntoConstraints = false
        label_03.translatesAutoresizingMaskIntoConstraints = false
        label_04.translatesAutoresizingMaskIntoConstraints = false

        
        //當屏寬大於兩個按鈕的寬度時,兩個按鈕的間隔的優先級會下降;
        //使用AlignAllLeft會提示Options mask required views to be aligned on a horizontal edge, which is not allowed for layout that is also horizontal.; 也就是說當我寫水平方向時的佈局時,其實只能使用水平相關的NSLayoutFormatOptions限定,不然會由於VFL語句解析出錯;
        //設置了左右邊距、間隔與寬度;則左右邊距和寬度優先;
        let hVFL = "H:|-10-[label_01(60)]-40-[label_02]-30-|"
        let hCons = NSLayoutConstraint.constraintsWithVisualFormat(hVFL, options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: ["label_01":label_01, "label_02":label_02])
        superView.addConstraints(hCons)
        
        let vVFL1 = "V:|-80-[label_01]"
        let vCons1 = NSLayoutConstraint.constraintsWithVisualFormat(vVFL1, options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: ["label_01":label_01, "label_02":label_02])
        superView.addConstraints(vCons1)
        


        
        
        
        //水平方向若是指定了上邊距與下邊距 和高度  則以上邊距和高度爲優先;
        //水平方向只是簡單居中
        let hVFL2 = "H:|-[label_03]-|"
        let hCons2 = NSLayoutConstraint.constraintsWithVisualFormat(hVFL2, options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["label_03":label_03])
        superView.addConstraints(hCons2)
        
        
        let hVFL3 = "H:|-[label_04(==label_03)]-|"
        let hCons3 = NSLayoutConstraint.constraintsWithVisualFormat(hVFL3, options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["label_03":label_03, "label_04":label_04])
        superView.addConstraints(hCons3)

        
        let vVFL3 = "V:|[label_03(>=60@900)]-50-[label_04(>=400@899)]-30@901-|"
        let vCons3 = NSLayoutConstraint.constraintsWithVisualFormat(vVFL3, options: NSLayoutFormatOptions.AlignAllLeft, metrics: nil, views: ["label_03":label_03, "label_04":label_04])
        superView.addConstraints(vCons3)


 

 


______________________________________________________________________________________________________________

12.15補充:
其實若是一個佈局中使用VFL,不可避免的整個佈局約束的語句甚至比佈局還要多,由於要對不一樣的佈局關係進行處理和限制,而涉及到動態修改就會更加麻煩;在個人項目中,不多再用到VFL了,可是有些場景不得不說VFL更方便;現在,個人作法是擴展了UIView的方法,用一些基本的方法作佈局,雖然理論上仍是使用frame進行的,可是若是可以有一個清晰的視圖層次和便於使用的分類方法,即使是很複雜的設計圖,也能夠很清晰的進行排布,由於註釋以及策略選用得當,一者維護起來也並不會困難,兩者仍可以適配各類機型,最主要我不須要去寫不少的約束代碼,以及去備註各個相關約束間的關係; 但自動佈局也並非就毫無用武之地,怎麼說呢,這個應該是哪種使用更加熟練,哪種就更爲適用,固然是以維護和知足設計要求的前提下。
相關文章
相關標籤/搜索