MyLayout是一個可以非常簡單和方便的實現各種界面布局的第三方開源庫。在我的github項目中大部分DEMO都是通過代碼來實現界面布局的,但這并不是表示MyLayout不支持XIB和SB。
在構建一個應用的MVC框架中,我們希望模型、視圖、控制這三部分都盡可能的低耦合,而蘋果推薦的視圖部分構建則是通過XIB或者SB來完成的。因為MyLayout中的各種布局視圖類其實都是從UIView派生的,因此MyLayout是完全可以和XIB以及SB混合使用的。
MyLayout的一些布局視圖屬性以及子視圖的擴展布局屬性是可以在XIB或者SB界面編輯器里面進行設置的。唯一的一個缺點是這些屬性的設置不能起到所見即所得的效果。 因為MyLayout是一個獨立而完整的界面布局框架,因此您可以和系統默認的AutoLayout混合使用,也可以完全獨立的單獨使用。
不和AutoLayout以及Size Classes結合使用的方法
當您使用MyLayout進行界面布局時,那么要求至少應該存在一個布局視圖,否則所有關于子視圖的擴展布局屬性都無效,因為子視圖的這些擴展屬性只有在布局視圖里面才有用。MyLayout是一個完整而獨立的布局體系,因此要求我們的布局視圖內的子視圖不能再通過設置AutoLayout的約束來進行布局了,因此我們可以在XIB或者SB中完全不需要AutoLayout以及Size Classess的特性。
-
第一步就是要將XIB或者SB中對AutoLayout和Size Classes的支持去掉:
取消對AutoLayout的支持 -
第二步就是將視圖控制器中的根視圖的類名轉化為對應的布局視圖類:
根視圖的類名轉換 第三步將類名轉換后您可以切換到Show the attributes inspector 標簽中進行布局視圖特有屬性的設置:
您會發現上面圖中出現了大量對MyLayout布局特有屬性以及子視圖的擴展布局屬性設置的地方。你可以在這里設置布局視圖以及子視圖的擴展屬性。我這里就分別設置了根視圖布局的topPadding屬性值為20,subviewVSpace屬性值為30。
在XCODE中如果您想要將視圖類的自定義屬性出現在attributes inspector 中的話,您需要在您的自定義屬性前面加上IBInspectable 關鍵字。比如下面的定義:
@property(nonatomic, assign) IBInspectable CGFloat myTop;
@property(nonatomic, assign) IBInspectable CGFloat myLeading;
@property(nonatomic, assign) IBInspectable CGFloat myBottom;
@property(nonatomic, assign) IBInspectable CGFloat myTrailing;
目前支持** IBInspectable關鍵字的屬性只有NSString、BOOL、int、float、double、CGSize、UIColor、UIImage等基本屬性,而對枚舉類型以及其他對象類型暫時不支持,那么假如我想設置枚舉類型的值比如布局視圖的gravity屬性時怎么辦呢?我們可以切換到Show the Identify inspector標簽中的 User Defined Runtime Attributes列表中
您會發現所有設置的擴展屬性都會在這里同時出現,因此您也可以在這里設置自定義的擴展屬性。 當某個自定義屬性無法在attributes inspector標簽中設置時,您可以在User Defined Runtime Attributes 進行設置,我在這里添加了對布局視圖gravity的設置。這里設置為1799的原因是MyGravity_Fill
的枚舉值就是1799(參考MyGravity類型枚舉值的定義)。通過gravity屬性設置了所有子視圖均分高度和以及寬度和布局視圖相等。設置完畢后我們分別按順序添加3個高度一致的子視圖如下:
上面的中我們可以看出,我們并不需要為子視圖設置任何附加的約束,我們也沒有為子視圖設置擴展屬性。我們只是按順序添加上去。下面的圖片就是實際的運行的結果:
從上面的例子里面我們可以看出MyLayout是可以完全和XIB以及SB無縫結合的,我們在沒有任何編碼的情況下,通過幾個簡單屬性的設置就實現了三個子視圖的垂直高度均分以及寬度和布局視圖相等以及每個子視圖之間間隔30的功能。(假如你用AutoLayout來設置約束的話,我相信要實現同樣的功能,您一定要設置非常多的約束來完成吧。)在這里唯一的缺陷就是MyLayout的屬性設置無法在XCODE界面編輯器中所見即所得。
上面的例子我們進行了簡單的布局擴展屬性設置,那么如果我們要實現布局套布局怎么辦呢? 既然我們可以把根視圖轉化為一個布局視圖類,那么我相信您可以舉一反三了。我們只要直接在根布局視圖中,先添加一個UIView視圖,然后把類名改為對應想要使用的布局視圖就可以了。我們將上面例子中的中間UILabel改為一個水平線性布局(需要注意的是在放置時需要將三個子視圖的frame的高度設置為一致,這個gravity屬性拉伸才能得到相同的高度。)。而水平線性布局則有2個子視圖:
上圖中我將中間的視圖的UIView類改為了MyLinearLayout。并設置了orientation屬性為1也就是水平線性布局方向,同時設置了水平線性布局的四周的邊界為10。下面就是運行的實際效果:
這樣是不是非常的簡單。當然如果您不想在XCODE的界面編輯器中設置布局視圖的各種屬性,而是想通過界面編輯器來建立視圖,然后通過代碼設置屬性或者要設置界面編輯器無法設置的布局屬性時。那么你需要將布局視圖設置為一個IBoutlet插座變量,然后在對應的地方設置布局屬性或者子視圖擴展屬性或者復雜的布局屬性就可以了:
和AutoLayout結合使用方法
上面的例子介紹的是在不使用AutoLayout時如何將MyLayout和XIB以及SB結合的場景,那么如果我們使用AutoLayout并且想用到MyLayout的布局視圖類怎么辦呢?答案很簡單:
MyLayout布局視圖本身就和其他普通視圖一樣通過AutoLayout來設置約束,而布局視圖里面的子視圖則不能使用AutoLayout來設置約束,而是用上面介紹的方式來設置各種布局屬性。
TangramKit對XIB以及SB的支持
目前TangramKit并沒有在XCODE的界面編輯器中定義出可設置的擴展屬性。因此當你用TangramKit進行界面布局時,您可以在XCODE的界面編輯器中將對應的界面視圖添加上去。然后通過建立插座變量來在代碼中設置各種布局屬性。
小結
從上面可以看出MyLayout并不排斥XIB或者SB,也并不排斥AutoLayout,相反如果您能夠靈活的運用那么將會大大的減少您構建應用的時間和精力。
最后歡迎大家訪問我的界面布局庫:
- MyLayout(OC版):https://github.com/youngsoft/MyLinearLayout
- TangramKit(Swift版):https://github.com/youngsoft/TangramKit
您的點贊和支持將是我開發的動力。。。