天天看點

MyLayout和XIB或SB的混合使用方法

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的特性。

  1. 第一步就是要将XIB或者SB中對AutoLayout和Size Classes的支援去掉:
    MyLayout和XIB或SB的混合使用方法
  2. 第二步就是将視圖控制器中的根視圖的類名轉化為對應的布局視圖類:
    MyLayout和XIB或SB的混合使用方法
  3. 第三步将類名轉換後您可以切換到Show the attributes inspector 标簽中進行布局視圖特有屬性的設定:
MyLayout和XIB或SB的混合使用方法

您會發現上面圖中出現了大量對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清單中

MyLayout和XIB或SB的混合使用方法

您會發現所有設定的擴充屬性都會在這裡同時出現,是以您也可以在這裡設定自定義的擴充屬性。 當某個自定義屬性無法在attributes inspector标簽中設定時,您可以在User Defined Runtime Attributes 進行設定,我在這裡添加了對布局視圖gravity的設定。這裡設定為1799的原因是

MyGravity_Fill

的枚舉值就是1799(參考MyGravity類型枚舉值的定義)。通過gravity屬性設定了所有子視圖均分高度和以及寬度和布局視圖相等。設定完畢後我們分别按順序添加3個高度一緻的子視圖如下:

MyLayout和XIB或SB的混合使用方法

上面的中我們可以看出,我們并不需要為子視圖設定任何附加的限制,我們也沒有為子視圖設定擴充屬性。我們隻是按順序添加上去。下面的圖檔就是實際的運作的結果:

MyLayout和XIB或SB的混合使用方法

從上面的例子裡面我們可以看出MyLayout是可以完全和XIB以及SB無縫結合的,我們在沒有任何編碼的情況下,通過幾個簡單屬性的設定就實作了三個子視圖的垂直高度均分以及寬度和布局視圖相等以及每個子視圖之間間隔30的功能。(假如你用AutoLayout來設定限制的話,我相信要實作同樣的功能,您一定要設定非常多的限制來完成吧。)在這裡唯一的缺陷就是MyLayout的屬性設定無法在XCODE界面編輯器中所見即所得。

上面的例子我們進行了簡單的布局擴充屬性設定,那麼如果我們要實作布局套布局怎麼辦呢? 既然我們可以把根視圖轉化為一個布局視圖類,那麼我相信您可以舉一反三了。我們隻要直接在根布局視圖中,先添加一個UIView視圖,然後把類名改為對應想要使用的布局視圖就可以了。我們将上面例子中的中間UILabel改為一個水準線性布局(需要注意的是在放置時需要将三個子視圖的frame的高度設定為一緻,這個gravity屬性拉伸才能得到相同的高度。)。而水準線性布局則有2個子視圖:

MyLayout和XIB或SB的混合使用方法

上圖中我将中間的視圖的UIView類改為了MyLinearLayout。并設定了orientation屬性為1也就是水準線性布局方向,同時設定了水準線性布局的四周的邊界為10。下面就是運作的實際效果:

MyLayout和XIB或SB的混合使用方法

這樣是不是非常的簡單。當然如果您不想在XCODE的界面編輯器中設定布局視圖的各種屬性,而是想通過界面編輯器來建立視圖,然後通過代碼設定屬性或者要設定界面編輯器無法設定的布局屬性時。那麼你需要将布局視圖設定為一個IBoutlet插座變量,然後在對應的地方設定布局屬性或者子視圖擴充屬性或者複雜的布局屬性就可以了:

MyLayout和XIB或SB的混合使用方法

和AutoLayout結合使用方法

上面的例子介紹的是在不使用AutoLayout時如何将MyLayout和XIB以及SB結合的場景,那麼如果我們使用AutoLayout并且想用到MyLayout的布局視圖類怎麼辦呢?答案很簡單:

MyLayout布局視圖本身就和其他普通視圖一樣通過AutoLayout來設定限制,而布局視圖裡面的子視圖則不能使用AutoLayout來設定限制,而是用上面介紹的方式來設定各種布局屬性。

MyLayout和XIB或SB的混合使用方法

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

您的點贊和支援将是我開發的動力。。。