StoryBoard+AutoLayout實戰開發小技巧

  使用xib、storybard、純代碼開發項目,這三種方法本人都嘗試過。純代碼格式寫的好,非常容易讀、理解。合作開發也確實比storyboard方便,不需要像xib、storyboard那樣經常切換幾個界面,經常爲了一個屬性連線而報錯,或者連線錯誤,純代碼編寫易控制,易讀。xib一般都是與代碼混合編寫,多用於自定義單元格之類的視圖。使用storyboard整個應用流程,結構顯得非常清楚,開發迅捷,但是自定義視圖不是特別方便,比如自定義一個遮罩HUD視圖。storyboard開發非常快,特別配合sizeclass、autolayout來適配6.0、7.0、8.0各種系統版本,4、5、6、6p各種屏幕尺寸非常之簡單。強烈推薦使用storyboard+autolayout來開發,蘋果的意願也是如此。這裏說一些storyboard和autolayout上的一些使用小技巧,也是對我前面部分工作的總結吧。

一、storyboard上的小技巧:

1、同時添加多個outlet

在IB中,選中一個view並右鍵點擊,將會出現灰色的HUD,可以在其上方便地拖拉或設定事件和outlet。你可以同時打開多個這樣的面板來一 次性添加所有outlet。右鍵點擊面板,隨便拖動一下面板,然後再打開另一個。你會發現前一個面板也留下來了,這樣你就可以方便地進行拖拽設定了。


2、多個Outlet HUD 

當然,對於成組和行爲類似的IBOutlet,應該直接使用IBOutletCollection來進行處理會更方便。


3、option鍵的妙用

(1)、可視化座標距離

選中一個label,然後按住option鍵並將鼠標移動到其他label上試試?你可以發現view之間的距離都以很容易理解的方式顯示出來了。不僅是同層次的view,被選中view與其他層次的view之間的距離關係也可以同樣顯示。


(2)、控件複製

選中一個label,然後按住option鍵,並用鼠標按住它拖動到另一個位置,結果有了兩label,新的label和原來label屬性相同,比cmd+c、cmd+v好用吧。

4、添加輔助線

雙擊某個view,然後Cmd+Shift+-或者Cmd+Shift+|即可在選中的view上添加一條水平或者垂直中心的輔助線。當然這個輔助線是可以隨意移動的。如果幹過設計的同學肯定明白這個的意義了,在之後的對其和設計變更的時候都有重要的參考價值。


5.添加自定義視圖

如圖這樣,把它當做xib來處理就行了。不用額外創建xib了,方便實用吧。


6.User Undefined Runtime Attributes妙用

例如在storyboard上設置這類屬性,圓角。

keypath寫上你想要設置的屬性,根據名字就知道它支持訪問對象的指定屬性的字符串序列,type就是屬性的類型,value還支持顏色哦。



7.使view的size與view的content相適應
選中任意的一個view,然後Editor->Size to Fit Content,或者簡單的按 ⌘=
接着就會按照下面的規則對選中view的Size做出與之Content對應的適應:
  • (1)ImageView/Button的size會設置爲圖像的原始size(最常見的用法)。
  • (2)Label/Button的size會被設置爲與當前text內容相當的尺寸。
  • (3)parent container view會與其subviews的frames相適應。
  • 8.Editor->Embed In View,UnEmbed
  • 你是不是對此素手無策呢:你希望將已有的一些subviews放入到不同的parent view中,甚至是不同的.xib文件中,但是當你把一些view重新設置之後,它們爲自動的位於新的parent view中心?

    如圖所示,你怎麼把1-12個數字label保持原有的樣子放入到scrollView中呢?

    點擊選中12個label,再選擇editor中的embed in view:


    把view拖到scrollview中去,再次點擊scrollView的unembed:


    OK,大功告成,很Esay是不,趕緊嘗試吧。

    9.對不在最上面的視圖進行位置移動。

    一般做法就是先將非最上面的view臨時設置到最上面,移動好位置之後,在設置回去。費時費力不討好。

    最簡單的方法:

    在document outline上雙擊view,就可以用箭頭移動view了。

    10.編輯出界的scrollView、tableview內容。

    當scrollView、tableview中控件超出了它們的frame,怎麼編輯控件呢?

    點擊控件,然後滑動滑輪,直到把目標控件給滑動出來。


二、Autolayout上的小技巧:

1.ScrollView上添加約束。

很多人都會遇到這種報錯:


這是因爲ScrollView的ContentSize沒有確定。

contentSize在佈局中實際上是scroll view的子view :content view的寬和高實現的。往往對於scrollview中的子view,我 們同樣也可以將其放在同一個父的container view中,然後將這個container view作爲scrollview的子view也即content view,這樣我們對scroll view 的佈局就可以簡化爲對content view的佈局,而content view裏面的子view相對於content view的佈局就是普通的佈局了,剩下的只需要我們解決好scroll view和content view的佈局即可。


這時有個奇怪的現象:

ContentView上下距離約束怎麼不與其高度約束衝突呢?

原來content view和scroll view的top, bottom, leading和trailing contstraints,這四個約束的使用在scroll view中做了變化:它不再是確定content view尺寸的依據,而是幫助scroll view中content view四周的邊界(or你可以理解爲留白),進而確定scroll view的contentSize屬性。

2.UILabel添加約束

Label只需要添加top, leading約束即可,寬度會根據文字內容多少自動適應。

假若把Label的height再次固定,則高度會自動適應。

比如:銀行名稱與尾號左對齊,並且尾號一直在名稱的底部。這裏切記勾選上label的preferred width 。不然iOS8.0以下程序會crash掉。





3.TableViewCell高度自適應

(1)設置好佈局約束條件,使得cell子視圖的邊緣固定(pin)到cell的contentView的邊緣(最重要的是要有頂部和底部的邊距約束條件),這樣cell就能確定自己的高度了。


(2)高度代理協議heightForRowAtIndexPath:千萬別實現它。

加上

tableview.rowheight=UITableviewAutomaticDimension;

tableview.estimatedRowheight=44;

(3)設置好正確的preferredMaxLayoutWidth  

[super layoutSubViews];

_contentLbl.preferredMaxLayoutWidth=_contentLbl.frame.size.width;

 [super layoutSubViews];

效果:


4、動畫處理

把滑動視圖的高度減小,_bgScrollViewHeightLayout定義在這裏:

@property (weak,nonatomic) IBOutLet NSLayoutConstraint *bgScrollViewHeightLayout;

[_bgScrollView layoutIfNeeded];

_bgScrollViewHeightLayout.constant=kScreenHeight-64-height;

[UIView animateWithDuration:duration animations:^{

[_bgScrollView layoutIfNeeded];

}];;

5、約束調試:

我們在iOS中遇到不可滿足的約束條件,我們只能在輸出的日誌中看到視圖的內存地址。尤其是在更復雜的佈局中,有時很難辨別出視圖的哪一部分出了問題。然而,在這種情況下,還有幾種方法可以幫到我們。

首先,當你在不可滿足的約束條件錯誤信息中看到NSLayoutResizingMaskConstraints時,你肯定忘了爲你某一個視圖設定translatesAutoResizingMaskIntoConstraints爲NO。Interface Builder中會自動設置,但是使用代碼時,你需要爲所有的視圖手動設置。

如果不是很明確那個視圖計算問題,你需要通過內存地址來辨認視圖。最簡單的方法是使用調試控制檯。你可以打印視圖本身或它父視圖的描述,甚至遞歸描述的樹視圖。這通常會提示你需要處理哪個視圖。

(1)使用po 命令

  

(2)一個更直觀的方法是在控制檯修改有問題的視圖,這樣你可以在屏幕上標註出來。比如,你可以改變它的背景顏色:

<span style="font-size:12px;">(lldb) expr ((UIView *)0x7731880).backgroundColor = [UIColor purpleColor] </span>

確保重新執行程序後改變不會在屏幕上顯示出來。還要注意將內存地址轉換爲(UIView *),以及額外的圓括號,這樣我們就可以使用點操作。另外,你當然也可以通過發送消息:

<span style="font-size:12px;">(lldb) expr [(UIView *)0x7731880 setBackgroundColor:[UIColor purpleColor]] </span>

(3)另一種方法是使用Instrument的allocation模板,根據圖表分析。一旦你從錯誤消息中得到內存地址(運行Instruments時,你從控制檯中獲得的錯誤消息),你可以將Instrument切換到Objects List的詳細視圖,並且用Cmd-F搜索那個內存地址。這將會爲你顯示分配視圖對象的方法,這通常是一個很好的暗示(至少找到創建視圖對象的代碼了)。

(4)你也可以在iOS中弄懂不可滿足的約束條件錯誤,這比改善錯誤消息來的更簡單。我們可以在一個category中重寫NSLayoutConstraint的描述,並且將視圖的tags包含進去:

<span style="font-size:12px;">@implementation NSLayoutConstraint (AutoLayoutDebugging) 
#ifdef DEBUG 
- (NSString *)description 
{ 
    NSString *description = super.description; 
    NSString *asciiArtDescription = self.asciiArtDescription; 
    return [description stringByAppendingFormat:@" %@ (%@, %@)", asciiArtDescription, [self.firstItem tag], [self.secondItem tag]]; 
} 
#endif 
@end </span>

如果是整數的屬性標籤信息是不夠的,我們還可以得到更多新奇的東西,爲視圖類增加我們自己命名的屬性,然後可以打印到錯誤消息中。我們甚至可以在Interface Builder中,使用identity inspector中的 “User Defined Runtime Attributes”爲自定義屬性分配值。

<span style="font-size:12px;">@interface UIView (AutoLayoutDebugging) 
- (void)setAbc_NameTag:(NSString *)nameTag; 
- (NSString *)abc_nameTag; 
@end 
  
@implementation UIView (AutoLayoutDebugging) 
- (void)setAbc_NameTag:(NSString *)nameTag 
{ 
    objc_setAssociatedObject(self, "abc_nameTag", nameTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
} 
  
- (NSString *)abc_nameTag 
{ 
    return objc_getAssociatedObject(self, "abc_nameTag");
} 
@end 
@implementation NSLayoutConstraint (AutoLayoutDebugging) 
#ifdef DEBUG 
- (NSString *)description 
{ 
		NSString *description = super.description; 
    NSString *asciiArtDescription = self.asciiArtDescription; 
    return [description stringByAppendingFormat:@" %@ (%@, %@)", asciiArtDescription, [self.firstItem abc_nameTag], [self.secondItem abc_nameTag]]; 
} 
#endif 
@end </span>

通過這種方法錯誤消息變得更可讀,並且你不需要找出內存地址對應的視圖。然而,對你而言,你需要做一些額外的工作以確保每次爲視圖分配的名字都是有意義。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章