天天看點

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。右鍵點選面闆,随便拖動一下面闆,然後再打開另一個。你會發現前一個面闆也留下來了,這樣你就可以友善地進行拖拽設定了。

StoryBoard+AutoLayout實戰開發小技巧

2、多個Outlet HUD 

當然,對于成組和行為類似的IBOutlet,應該直接使用IBOutletCollection來進行處理會更友善。

StoryBoard+AutoLayout實戰開發小技巧
StoryBoard+AutoLayout實戰開發小技巧

3、option鍵的妙用

(1)、可視化坐标距離

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

StoryBoard+AutoLayout實戰開發小技巧

(2)、控件複制

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

4、添加輔助線

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

StoryBoard+AutoLayout實戰開發小技巧

5.添加自定義視圖

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

StoryBoard+AutoLayout實戰開發小技巧

6.User Undefined Runtime Attributes妙用

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

keypath寫上你想要設定的屬性,根據名字就知道它支援通路對象的指定屬性的字元串序列,type就是屬性的類型,value還支援顔色哦。

StoryBoard+AutoLayout實戰開發小技巧
StoryBoard+AutoLayout實戰開發小技巧
StoryBoard+AutoLayout實戰開發小技巧

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中呢?

    StoryBoard+AutoLayout實戰開發小技巧
    點選選中12個label,再選擇editor中的embed in view:
    StoryBoard+AutoLayout實戰開發小技巧
    把view拖到scrollview中去,再次點選scrollView的unembed:
    StoryBoard+AutoLayout實戰開發小技巧

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

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

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

    最簡單的方法:

    在document outline上輕按兩下view,就可以用箭頭移動view了。

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

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

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

    StoryBoard+AutoLayout實戰開發小技巧

二、Autolayout上的小技巧:

1.ScrollView上添加限制。

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

StoryBoard+AutoLayout實戰開發小技巧

這是因為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的布局即可。

StoryBoard+AutoLayout實戰開發小技巧

這時有個奇怪的現象:

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掉。

StoryBoard+AutoLayout實戰開發小技巧
StoryBoard+AutoLayout實戰開發小技巧

3.TableViewCell高度自适應

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

StoryBoard+AutoLayout實戰開發小技巧

(2)高度代理協定heightForRowAtIndexPath:千萬别實作它。

加上

tableview.rowheight=UITableviewAutomaticDimension;

tableview.estimatedRowheight=44;

(3)設定好正确的preferredMaxLayoutWidth  

[super layoutSubViews];

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

 [super layoutSubViews];

效果:

StoryBoard+AutoLayout實戰開發小技巧

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 指令

StoryBoard+AutoLayout實戰開發小技巧

(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>
           

通過這種方法錯誤消息變得更可讀,并且你不需要找出記憶體位址對應的視圖。然而,對你而言,你需要做一些額外的工作以確定每次為視圖配置設定的名字都是有意義。

繼續閱讀