AutoLayout中的Visual Format Language

前言

今天使用Swift手寫AutoLayout時發現OC中的constraintWithItem方法竟然不翼而飛(後來發現其實是變成了init),只有原來的constraintsWithVisualFormat方法還健在,因爲之前沒有用過這個方法,所以就Google了下,然後就發現了一個神奇的東西:Visual Format Language,繼續Google發現有不少博客講了這個,但是看得不是很明白,忍不住打開官方文檔,發現它靜靜地躺在AutoLayout的附錄A中,看了一遍發現某些情況下真的是非常方便,而且看起來也蠻清晰。所以就把官方文檔翻譯了下,希望對大家有所幫助。

正文

Visual Format語言

該附錄告訴你如何使用AutoLayout中的Visual Format Language來添加約束,包括標準間距和尺寸,豎向佈局,以及不同優先級下的約束。另外,該附錄包含了完整的語法。

Visual Format語法

下面是使用Visual Format添加約束的一些例子。

標準間距
[button]-[textField]
這裏寫圖片描述

寬度約束
[button(>=50)]
這裏寫圖片描述

和父view做約束
|-50-[purpleBox]-50-|
這裏寫圖片描述

豎向佈局
V:[topField]-10-[bottomField]
這裏寫圖片描述

刷新視圖
[maroonView][blueView]
這裏寫圖片描述

優先級
[button(100@20)]
這裏寫圖片描述

等寬
[button1(==button2)]
這裏寫圖片描述

多條件
[flexibleButton(>=70,<=100)]
這裏寫圖片描述

完整的行佈局
|-[find]-[findNext]-[findField(>=20)]-|
這裏寫圖片描述

和完整性相比,標記法更傾向於良好的可視化。雖然大部分實用的用戶界面都可以用Visual Format語法來添加約束,但是仍然有一些不能。其中一個經常用到的約束就是寬高比約束(比如,imageView.width = 2 * imageView.height)。如果要爲它們添加約束,請使用constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:

Visual Format字符串語法

Visual Format字符串語法的定義如下(文本以代碼字體顯示;e代表空字符串)

符號 替代規則(意思就是第一列這個符號可以用後面的串來表示)
<visualFormatString> (<orientation<:)?
(<superview><connection>)?
<view>(<connection><view>)*
(<connection><superview>)?
<orientation> H|V
<superview> |
<view> [<viewName>(<predicateListWithParens>)?]
<connection> e|-<predicateList>-|-
<predicateList> <simplePredicate>|<predicateListWithParens>
<simplePredicate> <metricName>|<positiveNumber>
<predicateListWithParens> (<predicate>(,<predicate>)*)
<predicate> (<relation>)?(<objectOfPredicate>)(@<priority>)?
<relation> ==|<=|>=
<objectOfPredicate> <constant>|<viewName> (查看注意事項)
<priority> <metricName>|<number>
<constant> <metricName>|<number>
<viewName> 解析爲一個C標識符。
通過入參views傳入,入參views是key爲NSString類型,value爲NSView類型的一個字典,通過viewName這個key可以取到對應的NSView類型實例
<metricName> 解析爲一個C標識符。
通過入參metrics傳入,入參metrics是key爲NSString類型,value爲NSNumber類型的一個字典,通過metricName這個key可以取到對應的NSNumber類型實例
<number> C語言中可以用strtod_l解析的串,其實就是數字

注意:對於objectOfPredicate,只有在謂語的主語是一個view的寬度或者長度時,這個約束在viewName上纔會生效。也就是說,你可以使用[view1(==view2)]來指定view1view2的寬度一致。

如果語法有誤,會拋出一個帶診斷信息的異常,例如:

Expected ':' after 'V' to specify vertical arrangement
V|[backgroundBox]|
 ^

A predicate on a view's thickness must end with ')' and the view must end with ']'
|[whiteBox1][blackBox4(blackWidth][redBox]|
                                 ^

Unable to find view with name blackBox
|[whiteBox2][blackBox]
                     ^

Unknown relation. Must be ==, >=, or <=
V:|[blackBox4(>30)]|
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章