自定義視圖是iOS開發(fā)中經(jīng)常做的操作,它有助于創(chuàng)建美觀個性的頁面,同時也方便模塊化管理。最長做的自定義視圖差不多就是自定義cell了,蘋果很人性化的為自定義cell添加了xib文件,方便通過xib快速的拖拽控件。而自定義其他的視圖時,蘋果又默認禁止添加對應(yīng)的xib文件,不知道有沒有小伙伴為此困惑呢?首先說一下一般的自定義視圖的思想,一提到自定義視圖,比如自定義一個label,恐怕最早想到的就是繼承于UILabel,創(chuàng)建子類MyLabel,并在MyLabel中做一些自定義的操作。這里用到的是繼承,純代碼也的確經(jīng)常這樣寫。但是通過xib自定義視圖,一般不是繼承的關(guān)系,而是組合的關(guān)系。即xib文件中包含的視圖對象只是自定義類中的一個屬性,比如ViewController,xib中的view只是controller的一個view屬性;再比如cocos2d中,自定義一個MySprite,也往往不是直接繼承于CCSprite,而是組合的關(guān)系,繼承于CCNode,包含一個屬性為CCSprite對象。
本節(jié)將會使用xib的方式自定義上節(jié)中的HeaderView。demo地址:https://github.com/huibaoer/Demo_xib
1.創(chuàng)建工程,添加RootViewController。
2.創(chuàng)建Class HeaderView,F(xiàn)ile -> New -> File -> iOS Source (Cocoa Touch Class) -> Next -> Class命名為’HeaderView’,Subclass of選擇’UIView’,此時’Also create XIB file’為禁止選擇狀態(tài) -> Next -> 創(chuàng)建好HeaderView。
3.創(chuàng)建HeaderView.xib,F(xiàn)ile -> New -> File -> 左側(cè)選項卡選擇iOS下的User Interface -> 右側(cè)選擇View -> 點擊Next按鈕 -> 填寫xib文件名稱為‘HeaderView’ -> 點擊create創(chuàng)建xib文件。
4.編輯xib文件,選中文件中的默認view,在右側(cè)選中其屬性設(shè)置欄,Simulated Metrics下設(shè)置Size為Freeform,Status Bar為None,這樣就可以自由的拖拽view的大小且沒有頂部狀態(tài)欄。調(diào)整大小為320*100。在view上添加一個imageView作為頭像,一個label作為標題,再一個label作為描述,修改一下背景顏色,方便識別。
5.關(guān)聯(lián)HeaderView Class與xib文件,使用組合的方式將xib文件與HeaderView Class關(guān)聯(lián),即將xib中編輯好的視圖拖拽到HeaderView Class中作為一個屬性。選中xib文件的File’ Owner,選擇右側(cè)第三個選項卡,修改File’ Owner的Class為’HeaderView’。選擇Xcode右上側(cè)的一個兩個圈的按鈕,Xcode編輯區(qū)被分成兩部分,左側(cè)為xib,右側(cè)為xib對應(yīng)的File’s Owner(HeaderView),選中編輯好的視圖,點擊右鍵,會有該視圖支持的操作,選中New Referencing Outlet,拖拽到右側(cè)HeaderView上,創(chuàng)建一個outlet(引用輸出口,也就是一個屬性)。將其他需要outlet的控件以同樣的方法拖拽好。需要暴露在外邊的屬性拖拽到接口文件,不需要暴露給外面的盡量拖拽到延展中。
6.xib文件與HeaderView已經(jīng)關(guān)聯(lián)好,但是還差一步,自己添加的xib文件并不會像controller自帶的xib文件會在loadView中自動加載,所以需要在HeaderView的init方法中加載xib文件,并將加載好的視圖作為子視圖貼到HeaderView上,參見setupXib方法。代碼如下:
#import "UIKit/UIKit.h";
@interface HeaderView : UIView
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel;
@end
#import "HeaderView.h"
@interface HeaderView ()
@property (strong, nonatomic) IBOutlet UIView *contentView;
@end
@implementation HeaderView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setupXib];
}
return self;
}
- (void)setupXib {
[[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self options:nil];
[self addSubview:self.contentView];
}
7.一切準備就緒,最后在RootViewController的viewDidLoad方法中創(chuàng)建HeaderView對象并展示:
// 1. create HeaderView
HeaderView *headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 100, 320, 100)];
headerView.titleLabel.text = @"test title";
headerView.descriptionLabel.text = @"test description";
[self.view addSubview:headerView];