1. 程式人生 > >iOS開發技巧之:父子控制器

iOS開發技巧之:父子控制器

父子控制器

在 iOS 開發中我們經常用到的兩大父子控制器分別是:UINavigationController 和 UITabBarController。但是經常也會為了實現一些需求,自己去寫一個類似於 UITabBarController 的功能,也就是點選按鈕切換控制器,如圖:


QQ

功能都類似於 UITabBarController,點選切換控制器。只不過將 UITabBarController 底部的按鈕,移到頂部,或者其他位置去了。這時候就得自己去實現一個父子控制器。

實現

完成介面如圖所示:


父子控制器.gif

首先新建一個專案,建立一個父控制器,然後建立三個子控制器,如圖:


目錄結構

對父控制器上面的三個選單按鈕分別新增 tag 來進行區分,拖一個點選事件,都跳轉到同一個方法。然後在父控制器裡面,進行子控制器的新增和切換操作:

@interface ViewController ()

@property (nonatomic, weak) UIViewController *currentVC;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 新增子控制器
    [self
addChildViewController:[[OneViewController alloc] init]]; [self addChildViewController:[[TowViewController alloc] init]]; [self addChildViewController:[[ThreeViewController alloc] init]]; } - (IBAction)clickMenu:(UIButton *)btn { // 取出選中的這個控制器 UIViewController *vc = self.childViewControllers[btn.tag]; // 設定尺寸位置
vc.view.frame = CGRectMake(0, 70, self.view.frame.size.width, self.view.frame.size.height - 50); // 移除掉當前顯示的控制器的view(移除的是view,而不是控制器) [self.currentVC.view removeFromSuperview]; // 把選中的控制器view顯示到介面上 [self.view addSubview:vc.view]; self.currentVC = vc; }

其中,currentVC 屬性用來記錄當前正在顯示的 view。如果進行切換操作,要把 currentVC 從父類的 view 中移除掉。
不移除的後果是:介面上會顯示出所有的 view,只不過你只能看到最上面那個。會增加系統的開銷。

整體還是非常簡單的,在 UIViewController 裡面,有一個數組用來專門存放子控制器,可以方便進行管理。當然也可以自己在父控制器裡面建立一個數組來對子控制器進行管理。不過這樣會產生一些問題,稍後會說到。

我 Demo 中的例子非常簡單。實際開發中,子控制器的 View 可能是 UITableView 或者其他更為複雜的介面佈局,這個時候使用父子控制器顯得尤為重要。這樣子控制器可以對自己的 view 進行管理,不必什麼操作都放到父控制器中,也符合高內聚,低耦合的開發原則。

結論

使用系統帶的 childViewControllers 陣列有很多好處。
1、當父控制器有一些重大的事件發生,可以通知到自控制器。比如:螢幕旋轉等。
2、如果程式是一個基於 UINavigationController 的邏輯,那麼子控制器可能會做以下呼叫 self.navigationController。如果不把子控制器新增到 childViewControllers 陣列中,子控制器拿到的self.navigationController為空。

結論:不要自己建立陣列來管理子控制器,用 UIViewController 自帶的 childViewControllers 陣列可以避免掉很多不必要的麻煩。

擴充套件

可以在整體佈局中巢狀一個 ScrollView,使子控制器可以進行滑動切換,實現類似於網易新聞的效果。
也可以在切換 view 時加入動畫。