iOS中載入xib

語言: CN / TW / HK

highlight: a11y-dark theme: cyanosis


「這是我參與11月更文挑戰的第27天,活動詳情檢視:2021最後一次更文挑戰

關於 xib 或 storyboard

  • 共同點
    • 都用來描述軟體介面
    • 都用 interface builder 工具來編輯
    • 本質都是轉換成程式碼去建立控制元件
  • 不同點
    • xib是輕量級的,用來描述區域性UI介面
    • storyboard是重量級的,用來描述整個軟體的多個介面,並且能夠展示多個介面的跳轉關係

載入xib

xib 檔案在編譯的後會變成 nib 檔案

11975486-4f7dfbf345c0bff5.png

  • 第一種載入方式 js NSArray * xibArray = [[NSBundle mainBundle]loadNibNamed:NSStringFromClass(self) owner:nil options:nil] ; return xibArray[0];
  • 第二種載入方式 js UINib *nib = [UINib nibWithNibName:NSStringFromClass(self) bundle:nil]; NSArray *xibArray = [nib instantiateWithOwner:nil options:nil]; return xibArray[0]; xibArray中log列印 log.png

控制器載入xib

  1. 首先需要對 xib 檔案進行一些處理,開啟 xib 檔案
  2. 點選 "File‘s Owner",設定 Class 為 xxxViewControler 點選"File‘s Owner",設定Class為xxxViewControler.png

  3. 右鍵 "Files‘s Owner",裡面有個預設的IBOutlet變數view,看一下後面有沒有做關聯,如果沒有就拉到下面的View和檢視做個關聯

    Files‘s Owner與View做關聯

  4. 第一種載入方式,傳入指定的 xib(如CustomViewController) js CustomViewController *custom = [[CustomViewController alloc]initWithNibName:@"CustomViewController" bundle:nil];

  5. 第二種載入方式,不指定 xib js CustomViewController *custom = [[CustomViewController alloc]initWithNibName:nil bundle:nil];

    • 第一步:尋找有沒有和控制器類名同名的xib,如果有就去載入(XXViewController.xib)

      控制器類名同名的xib.png

    • 第二步:尋找有沒有和控制器類名同名但是不帶Controller的xib,如果有就去載入(XXView.xib)

      11975486-e40e19dd11cafbc5.png

    • 第三步:如果沒有找到合適的 xib,就會建立一個 view(白色View,為系統自己建立的)


xib自定義控制元件與程式碼自定義的區別

這是自定義的一個 view,我們通過不同的初始化方式去判斷它的執行方法

```js

import "CustomViw.h"

@implementation CustomViw - (instancetype)init{ self = [super init]; if (self) { NSLog(@"%s",func); } return self; }

  • (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { NSLog(@"%s",func); } return self; }

  • (instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super initWithCoder:aDecoder]) { } NSLog(@"%s",func); return self; }

  • (void)awakeFromNib{ [super awakeFromNib]; NSLog(@"%s",func); } @end ```

  • 通過 init 方法初始化自定義控制元件 ```js @implementation ViewController

    • (void)viewDidLoad { [super viewDidLoad]; CustomViw *customView = [[CustomViw alloc] init]; } @end ``` log:

    通過init方法初始化自定義控制元件log列印.png

  • 通過載入 xib 方法初始化自定義控制元件 ```js @implementation ViewController

    • (void)viewDidLoad { [super viewDidLoad]; CustomViw *customView = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([CustomViw class]) owner:nil options:nil] lastObject]; } @end ```

    log(列印三次是因為CustomViw的xib檔案裡有三個View) 通過載入xib方法初始化自定義控制元件log列印.png

小結:
- 通過程式碼初始化自定義控制元件是不會自動載入xib的,它會執行 initWithFrameinit - 通過載入 xib 初始化自定義控制元件,僅僅執行 initWithCoderawakeFromNib,如果要通過程式碼修改 xib 的內容,一般建議放在 awakeFromNib 方法內


控制元件封裝

一般封裝一個控制元件,為了讓開發者方便使用,通常會在自定義的控制元件中編寫倆個方法初始化方法,這樣不管是通過 init 還是載入xib都可以實現相同的效果 ```js

import "CustomViw.h"

@implementation CustomViw

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

  • (void)awakeFromNib{ [super awakeFromNib]; [self setup]; }

  • (void)setup{ [self setBackgroundColor:[UIColor redColor]]; } @end ```