在Storyboard中使用由xib定義的view

前言

在iOS開發(fā)中悲柱,使用storyboard的某些場景下我們可能希望同時使用xib定義一些可以重復利用的view钧敞,并在storyboard中調(diào)用锅必。本文將分享一種此類xib bridge的簡單實現(xiàn)方式伐脖。

實現(xiàn)思路

本方法的思路是將xib的File's Owner所對應的UIView作為placeholderView介粘,其作用只是在storyboard中起到占位作用秉犹,并承載storyboard中與xib自定義view相關的AutoLayout約束蛉谜,其背景色將被設為[UIColor clearColor],并且不顯示任何內(nèi)容崇堵。顯示自定義內(nèi)容的任務將交給一個UIView--contentView型诚,它將作為placeholderView的子視圖。

為了使在storyboard中作用于placeholderView的AutoLayout約束能夠自動的作用于contentView鸳劳,可以向placeholderView添加NSLayoutRelationEqual約束狰贯,讓placeholderViewcontentView的上下左右四個NSLayoutAttribute分別完全相等,這樣contentView在storyboard中的的frame將完全和placeholderView相同,從而達到目的涵紊。

以上方法同樣可以適用于xib的某個子view是另外一個xib的情形傍妒。

實現(xiàn)方法

首先進行如下準備工作

  • 創(chuàng)建一個xib,用于實現(xiàn)子view的自定義內(nèi)容摸柄,本文中命名為CoverView.xib颤练。
  • 創(chuàng)建一個UIView的子類,作為placeholderView的基類塘幅,用于進行xib bridge相關的添加約束和添加contentView等工作昔案,本文中命名為XibBridgeBaseView
  • 創(chuàng)建一個XibBridgeBaseView的子類电媳,用于存儲xib中自定義內(nèi)容的相關屬性并進行相關操作踏揣,本文中命名為CoverView

實現(xiàn)子view的xib文件

首先需要在identity inspector中將xib文件的File's Owner設置成為創(chuàng)建好的CoverView

Files-Owner-identity-inspector.jpg

接下來我們就可以在xib中自動創(chuàng)建的UIView子視圖中進行自定義UI了,此時可以在CoverView類中創(chuàng)建該UIView子視圖(這里命名為contentView)以及其他UI組件的IBActionIBOutlet等匾乓。

setup-IBOutlet-and-IBAction.jpg

實現(xiàn)占位視圖的基類

作為placeholderView的基類捞稿,XibBridgeBaseView中定義了如下的一個方法,用于從nib中載入contentView并添加進占位視圖的子視圖中拼缝,其中XibBridgeBaseViewinitWithCoder:方法將使用其派生子類的類名作為xib的名字娱局,因此子類和其所對應的xib文件應該使用相同的命名。

@implementation XibBridgeBaseView
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setupXibBridgeWithPlaceholderViewNibName:NSStringFromClass([self class])];
    }
    return self;
}

- (void)setupXibBridgeWithPlaceholderViewNibName:(NSString *)placeholderViewNibName {
    UIView *contentView =[[[NSBundle mainBundle] loadNibNamed:placeholderViewNibName
                                                        owner:self
                                                      options:nil] objectAtIndex:0];
    
    [self setBackgroundColor:[UIColor clearColor]];
    [self addSubview:contentView];
    [self setXibBridgeConstraintsToContentView:contentView];
}

其中- (void)setXibBridgeConstraintsToContentView:(UIView *)contentView方法主要是實現(xiàn)前文提到的通過向占位視圖添加NSLayoutRelationEqual約束讓placeholderViewcontentView的上下左右四個NSLayoutAttribute分別完全相等:

@implementation XibBridgeBaseView
- (void)setXibBridgeConstraintsToContentView:(UIView *)contentView {
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|"
                                                                options:0
                                                                metrics:nil
                                                                  views:NSDictionaryOfVariableBindings(contentView)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|"
                                                                options:0
                                                                metrics:nil
                                                                  views:NSDictionaryOfVariableBindings(contentView)]];
    //為保證AutoLayout生效咧七,必須加上下面這句話
    contentView.translatesAutoresizingMaskIntoConstraints = NO;    
}

實現(xiàn)占位視圖的實際類

作為placeholderView的實際類衰齐,每創(chuàng)建一個需要被橋接的xib時就要創(chuàng)建一個對應的實際類(本文中為CoverView類),CoverView中將包含在xib中定義的自定義UI相關的屬性和操作:

@interface CoverView : XibBridgeBaseView

@property (weak, nonatomic) IBOutlet UILabel *headerLabel;
@property (weak, nonatomic) IBOutlet UIButton *submitButton;
@property (strong, nonatomic) IBOutlet UIView *contentView;
@implementation CoverView
- (IBAction)submitButtonClicked:(UIButton *)sender {
    NSLog(@"Hello World!");
}

因為我們是用父storyboard或者xib來調(diào)用placeholderView的继阻,實際使用中只需要將placeholderView的實際類繼承于基類xibBridgeBaseView耻涛,即可實現(xiàn)橋接功能。該placeholderView的其他初始化工作可以放在- awakeFromNib中進行

@implementation CoverView
- (void)awakeFromNib {
    self.contentView.backgroundColor = [UIColor clearColor];
    [self.contentView.layer setBorderColor:[[UIColor whiteColor] CGColor]];
    [self.contentView.layer setBorderWidth:1.0];
}

在父的storyboard或者xib中調(diào)用placeholderView

做完以上步奏后瘟檩,只需在父storyboard或者xib中拖一個UIView來作為placeholderView抹缕,并在identity inspector中將其class屬性設置成為對應的placeholderView的實際類即可。

set-class-for-placeholderView-in-storyboard.jpg

結(jié)語

在使用如上方法來進行xib橋接的過程中需要注意一下幾點使用方式:

  • 在父的storyboard或者xib中墨辛,只需要對拖入的placeholderView添加AutoLayout約束即可
  • 在子xib中各個UI組件只需要跟contentView建立AutoLayout約束即可
  • 對于placeholderView的identity inspector相關參數(shù)需要在子xib中對File's Owner進行設置
  • 對于placeholderView的attribute inspector相關參數(shù)需要在父storyboard或者xib中進行設置

對于xib橋接問題大神SUNNYXX給出了一個更高端的解決方案卓研,利用到了iOS runtime相關的技術。


本文個人博客地址: http://wty.im/2016/02/29/use-view-defined-by-xib-in-storyboard/
Github: https://github.com/wty21cn/

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末睹簇,一起剝皮案震驚了整個濱河市奏赘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌太惠,老刑警劉巖志珍,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垛叨,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門嗽元,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敛纲,“玉大人,你說我怎么就攤上這事剂癌∮傧瑁” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵佩谷,是天一觀的道長旁壮。 經(jīng)常有香客問我,道長谐檀,這世上最難降的妖魔是什么抡谐? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮桐猬,結(jié)果婚禮上麦撵,老公的妹妹穿的比我還像新娘。我一直安慰自己溃肪,他們只是感情好免胃,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惫撰,像睡著了一般羔沙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厨钻,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天扼雏,我揣著相機與錄音,去河邊找鬼莉撇。 笑死呢蛤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的棍郎。 我是一名探鬼主播其障,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涂佃!你這毒婦竟也來了励翼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤辜荠,失蹤者是張志新(化名)和其女友劉穎汽抚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伯病,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡造烁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惭蟋。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡苗桂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出告组,到底是詐尸還是另有隱情煤伟,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布木缝,位于F島的核電站便锨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏我碟。R本人自食惡果不足惜放案,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怎囚。 院中可真熱鬧卿叽,春花似錦、人聲如沸恳守。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽催烘。三九已至沥阱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伊群,已是汗流浹背考杉。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舰始,地道東北人崇棠。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像丸卷,于是被迫代替她去往敵國和親枕稀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容