xib的冷使用2------嵌套使用xib

前言

關(guān)于 initWithNibName 和 loadNibNamed 的區(qū)別和聯(lián)系

參考:關(guān)于 initWithNibName 和 loadNibNamed 的區(qū)別和聯(lián)系

如果執(zhí)行
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"RemarkView" owner:self options:nil];
語句,發(fā)現(xiàn)崩潰届巩,請檢查對應(yīng)的.xib文件中的控件關(guān)聯(lián)是否正確硅瞧。比如如果控件類型錯了等就會導致此句崩潰。

嵌套使用xib

參考:Nested Xib Views - 使用XIB實現(xiàn)嵌套自定義視圖

有一個復雜的視圖viewA恕汇,上面有很多的subview腕唧,我們?yōu)榱烁咏怦睿瑢iewA的某部分子視圖瘾英,又獨立成一個viewB枣接。

現(xiàn)在的問題是,你的viewB已經(jīng)是用xib來生成的了方咆。那么
當你viewA也是使用xib時候月腋,你會發(fā)現(xiàn)即使你做了該做的在A.xib中添加一個UIView蟀架,然后將這個view的定制類從UIView改為類B瓣赂。發(fā)現(xiàn)B壓根沒顯示出來榆骚。這是什么情況呢?

父視圖superView添加子視圖subView的兩種方法

方法①:[self.view addSubView:view1];
方法②:xib上添加subView

subView的創(chuàng)建的兩種方式:

1煌集、代碼生成妓肢,
CustomView1 *view1 = [[CustomView1 alloc] init];
view1.titleLabel = [[UILabel alloc] init....
view1.imageView = [[UIImage alloc] init..
....

2、xib生成
xib生成也有幾種方法

①一個類只有一種xib苫纤,通過設(shè)置File's Owner將其設(shè)為某個類的所有者碉钠,同時進行關(guān)聯(lián)


一個類只有一種xib.png

這種xib方式創(chuàng)建的view,提取CustomView 的 xib 中的內(nèi)容的方法為:

        UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil];
        NSArray *views = [nib instantiateWithOwner:self options:nil];
        UIView *containerView = [views objectAtIndex:0];

如果CustomView.m(如OrderPriceInfoView1.m)未做任何處理卷拘,則其他需要添加CustomView的view上的寫法應(yīng)為如下:

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit {
    UINib *nib1 = [UINib nibWithNibName:NSStringFromClass([OrderPriceInfoView1 class]) bundle:nil];
    NSArray *views1 = [nib1 instantiateWithOwner:self options:nil];
    OrderPriceInfoView1 *orderPriceInfoView1 = [views1 objectAtIndex:0];
    orderPriceInfoView1.frame = self.bounds;
    [self addSubview:orderPriceInfoView1];
    self.orderPriceInfoView1 = orderPriceInfoView1;
    
    UINib *nib2 = [UINib nibWithNibName:NSStringFromClass([OrderPriceInfoView2 class]) bundle:nil];
    NSArray *views2 = [nib2 instantiateWithOwner:self options:nil];
    OrderPriceInfoView2 *orderPriceInfoView2 = [views2 objectAtIndex:0];
    orderPriceInfoView2.frame = self.bounds;
    [self addSubview:orderPriceInfoView2];
    self.orderPriceInfoView2 = orderPriceInfoView2;
    
    UINib *nib3 = [UINib nibWithNibName:NSStringFromClass([OrderPriceInfoView3 class]) bundle:nil];
    NSArray *views3 = [nib3 instantiateWithOwner:self options:nil];
    OrderPriceInfoView3 *orderPriceInfoView3 = [views3 objectAtIndex:0];
    orderPriceInfoView3.frame = self.bounds;
    [self addSubview:orderPriceInfoView3];
    self.orderPriceInfoView3 = orderPriceInfoView3;
}

而我們這里為了不頻繁的在每個需要使用到這個CustomView的時候喊废,都要寫一遍這個xib中的內(nèi)容加載代碼,所以我們選擇將這個xib中的內(nèi)容加載代碼寫到CustomView初始化方法中栗弟。
例如:

//CustomXibView.m
- (instancetype)init {
    self = [super init];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit {
    UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:nil];
    NSArray *views = [nib instantiateWithOwner:self options:nil];
    UIView *containerView = [views objectAtIndex:0];
    [self addSubview:containerView];
    
    //CGRect newFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    //containerView.frame = newFrame;
    [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(self);
    }];
}

這樣操作后污筷,就不用再每次需要使用到CustomView的時候,都需要重復寫一遍xib中內(nèi)容的加載代碼了乍赫。

也因此瓣蛀,這樣改后,上面的代碼可改成如下

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit {
    OrderPriceInfoView1 *orderPriceInfoView1 = [[OrderPriceInfoView1 alloc] init];
    orderPriceInfoView1.frame = self.bounds;
    [self addSubview:orderPriceInfoView1];
    self.orderPriceInfoView1 = orderPriceInfoView1;
    
    OrderPriceInfoView2 *orderPriceInfoView2 = [[OrderPriceInfoView2 alloc] init];
    orderPriceInfoView2.frame = self.bounds;
    [self addSubview:orderPriceInfoView2];
    self.orderPriceInfoView2 = orderPriceInfoView2;
    
    OrderPriceInfoView3 *orderPriceInfoView3 = [[OrderPriceInfoView3 alloc] init];
    orderPriceInfoView3.frame = self.bounds;
    [self addSubview:orderPriceInfoView3];
    self.orderPriceInfoView3 = orderPriceInfoView3;
}

但其實這個更方便的地方是雷厂,當你的這個CustomView是通過xib嵌套到其他xib中的時候惋增,只需要拖動一個view上去改鲫,并將該view的類設(shè)置好就可以啦。

②一個類可能有多種xib,
試想如果你的viewA是使用代碼的話呢纫塌,你是不是會在創(chuàng)建A類子視圖的時候讲弄,把B通過[NSBundle mainBundle] loadNib...]的方法寫進去。

所以這里的問題怎披,也是一樣瓶摆,針對我們將一個xib文件作為subview放入另一個xib中的話,作為subview的這個xib并不會自動被系統(tǒng)載入內(nèi)存状飞,這就出現(xiàn)了上面例子中的看不到B.xib。所以我們需要手動載入B.xib酵使。具體的做法是在類A的initWithCoder:(NSCoder)方法中使用

  //正確做法
  UINib *nib1 = [UINib nibWithNibName:NSStringFromClass([OrderPriceInfoView1 class]) bundle:nil];
   NSArray *views1 = [nib1 instantiateWithOwner:self options:nil];
   self.view1 = [views1 objectAtIndex:0];

而不是(會導致崩潰原因不詳)

  //錯誤做法
  NSArray *views1 = [[NSBundle mainBundle] loadNibNamed:[self class] owner:nil options:nil];
  self.view1 = [views1 objectAtIndex:0];

方法手動載入B.xib即可口渔,然后將其作為subview添加到當前view中穿撮。

eg:

使用IB自定義了一個View,然后又在其他的xib文件中使用了這個View

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末攻礼,一起剝皮案震驚了整個濱河市秘蛔,隨后出現(xiàn)的幾起案子傍衡,更是在濱河造成了極大的恐慌,老刑警劉巖蛙埂,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绣的,死亡現(xiàn)場離奇詭異,居然都是意外死亡芭概,警方通過查閱死者的電腦和手機惩嘉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門文黎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人桩蓉,你說我怎么就攤上這事劳闹∏⑺玻” “怎么了片任?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長位他。 經(jīng)常有香客問我,道長舞竿,這世上最難降的妖魔是什么窿冯? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任醒串,我火速辦了婚禮,結(jié)果婚禮上仰挣,老公的妹妹穿的比我還像新娘缠沈。我一直安慰自己,他們只是感情好洲愤,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布柬赐。 她就那樣靜靜地躺著,像睡著了一般息楔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天后添,我揣著相機與錄音,去河邊找鬼馅精。 笑死,一個胖子當著我的面吹牛洲敢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睦优,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼汗盘,長吁一口氣:“原來是場噩夢啊……” “哼询一!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菱阵,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤送粱,失蹤者是張志新(化名)和其女友劉穎掂之,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體世舰,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡跟压,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年震蒋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钾虐。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡笋庄,死狀恐怖倔监,靈堂內(nèi)的尸體忽然破棺而出菌仁,到底是詐尸還是另有隱情,我是刑警寧澤谱秽,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布疟赊,位于F島的核電站,受9級特大地震影響泪掀,放射性物質(zhì)發(fā)生泄漏异赫。R本人自食惡果不足惜头岔,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一峡竣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧适掰,春花似錦、人聲如沸载城。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽睬澡。三九已至眠蚂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間米绕,已是汗流浹背瑟捣。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工迈套, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桑李,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓贵白,卻偏偏與公主長得像禁荒,于是被迫代替她去往敵國和親角撞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

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