創(chuàng)建Xib前的準(zhǔn)備
- 仍然使用single view 單例模式創(chuàng)建
- 不去刪除原生的Main.storyboard
- 這樣做可以省去在Appdelegate中的 didFinishLaunch去設(shè)置self.window.view及設(shè)定rootviewController
- 這種的方式。VC的入口仍然是Main.storyboard及其對(duì)應(yīng)的 ViewController.m
創(chuàng)建Xib
- 下面著重講一下之前的一個(gè)認(rèn)知誤區(qū):即 一個(gè)XIB ≠ 一個(gè)ViewController
- 有兩個(gè)函數(shù)可以載入XIB上的內(nèi)容
-
initWithNib
self.vc = [[ViewController alloc] initWithNibName:@"ViewController"
bundle:nil]; -
loadNibNamed: owner: options:
self.view = [[NSBundle mainBundle] loadNibNamed:@"SpecialThird"
owner:self
options:nil].lastObject;
-
- 下面著重來介紹下這兩種方式究履。
XIB作為ViewContrller的對(duì)應(yīng)UI使用
使用initWithNib
- 有一個(gè)大前提,如上面創(chuàng)建Xib前的準(zhǔn)備 所述最仑,通過單例創(chuàng)建且不刪除main.storyboard
- 通過cmd+n 新建一個(gè)ViewController的子類DIYViewController,創(chuàng)建時(shí)盯仪,有一個(gè)Also Create XIB file
- 創(chuàng)建之后,可以在這個(gè)ViewController上拖曳/添加控件蜜葱,這些都與storyboard一樣全景,沒有差異。再次不贅述牵囤,注意下面這張圖即可
Paste_Image.png
XIB 作為自定義的View使用 __ 重點(diǎn) __
使用loadNibNamed: owner: options:
- 此時(shí)的XIB相當(dāng)于我們的一個(gè)自定義UIView
- 先通過cmd+n 去interface里面創(chuàng)建一個(gè)empty的XIB(和上面不同爸黄,上面是通過隊(duì)要你管的VC類創(chuàng)建XIB揭鳞,這里是直接先創(chuàng)建XIB)
- 此時(shí)XIB里沒有UI界面,從控件中拖取一個(gè)UIView進(jìn)來
- 創(chuàng)建一個(gè)DIYView繼承UIView
- 指明第三步創(chuàng)建的UIView的類為DIYView野崇,并在上面添加控件,如下圖,及對(duì)應(yīng)的實(shí)現(xiàn)代碼
注意圖中的說明鳖轰。class的類為NSObject何上面的自定義vc不同! - NSBundle會(huì)動(dòng)態(tài)實(shí)現(xiàn)蕴侣,也就是說一旦在viewdidload中創(chuàng)建,就會(huì)立即出現(xiàn)
Paste_Image.png
// SpecialView.m
// ForTestingXIB
#import "SpecialView.h"
@interface SpecialView()
@property (weak, nonatomic) IBOutlet UILabel *ShowLabel;
@end
@implementation SpecialView
- (IBAction)changeLabel:(UIButton *)sender {
self.ShowLabel.text = @"Now changed";
}
下面是如何在main.storyboard 對(duì)應(yīng)的 ViewController中插入
- 代碼中包括了上面的兩種方法
- 重點(diǎn)說一下loadNibNamed這個(gè)函數(shù)辱志。
- 這個(gè)函數(shù)的返回值是一個(gè)由UIView(或其子類)組成的 NSArray如下
NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"SpecialThird" owner:self options:nil]; NSLog(@"數(shù)組長度 = %lu",array.count); NSLog(@"數(shù)組[0] = %@",array[0]);
- 打印出的數(shù)組日志為
2015-12-29 16:13:34.044 ForTestingXIB[11606:743852] 數(shù)組長度 = 1 2015-12-29 16:13:34.045 ForTestingXIB[11606:743852] 數(shù)組[0] = <SpecialView: 0x7fb99951d920; frame = (0 0; 600 600); autoresize = RM+BM; layer = <CALayer: 0x7fb99951aa10>>
- 數(shù)組中只有一個(gè)元素狞膘,通過獲取他可以獲取控件
#import "ViewController.h"
#import "SecViewController.h"
#import "SpecialView.h"
#import "Masonry.h"
@interface ViewController ()
@property (strong,nonatomic) SecViewController *vc;
@property (strong,nonatomic) SpecialView *view3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.vc = [[SecViewController alloc] initWithNibName:@"SecViewController" bundle:nil];
SpecialView *view = [[NSBundle mainBundle] loadNibNamed:@"SpecialThird"
owner:self
options:nil].lastObject;
[self.view insertSubview:view
atIndex:1];
self.view3 = view;
}
關(guān)于Load創(chuàng)建辦法的幾點(diǎn)補(bǔ)充
我在寫應(yīng)用實(shí)例demo的時(shí)候,發(fā)現(xiàn)一個(gè)問題客冈。
如果沒有按照上述的順序去創(chuàng)建:
- 先通過創(chuàng)建類的同時(shí)創(chuàng)建XIB
- 將這個(gè)XIB中的UIView替換成自定義的DIYView
a.如果不替換而在上面添加控件,編譯可以通過但程序會(huì)崩潰
采用上述兩點(diǎn)操作的話场仲,一旦在ViewDidLoad中賦值,運(yùn)行的時(shí)候就會(huì)立即顯示load創(chuàng)建的XIB中的View
self.view3 = [[NSBundle mainBundle] loadNibNamed:@"ThirdVC"
owner:self
options:nil].lastObject;
其中的原因:
如下圖所示渠缕,通過ViewController創(chuàng)建的XIB中默認(rèn)會(huì)關(guān)聯(lián)這個(gè)Outlet,所以在我們用load創(chuàng)建的時(shí)候會(huì)立刻載入這個(gè)View.而正常按步驟創(chuàng)建的話是沒有這個(gè)Outlet的亦鳞,如下圖3
Paste_Image.png
圖1!
Paste_Image.png
圖2
Paste_Image.png
圖3
TBD 問題!
上面用到了insert view之后遭笋,顯示出來的圖形變成了疊加,是為何
Paste_Image.png