本文先講解簡單的分段控制器UISegmentedControl的使用,然后具體講解它最常使用的場景:同一個控制器中實現多個View的切換。
文章構思:
1、先直接講解一張UI效果圖的四種實現方式。
2、對UISegmentedControl類的各種屬性和各種方法的講解。
UISegmentedControl控件的很大的使用場景基本像下面這張圖顯示的一樣,在同一個控制器中實現多個View的切換。
結合這張圖,我先講解下產品的要求。導航欄上面放置一個UISegmentedControl控件,可以切換“空間”數據、“活動”數據。並且空間數據的展示界面和活動數據的展示界面是不一樣的UI布局。
當然,如果這多個界面的UI布局是一樣的,不同的只是數據,那肯定就采用同一個控制器、同UI界面,賦予不同的數據,然后刷新就好了。
為了實現這樣的效果,一般市面上有四種實現方案,我比較偏向使用第三種。第四種也就是將前面兩種方法結合起來使用。
第一種方式:如上圖所示,實現的思路就是使用UIScrollView控件,將ViewA和ViewB都放置在UIScrollView中,然后當點擊UISegmentedControl控件時,使用UIScrollView對象的內容偏移的方式,達到所需效果。
好處:兩個View是放置在ScrollView上面的,View切換過程中,比較順暢、可以同時存在ViewA的右半部分、ViewB的左半部分。
壞處:ViewA和ViewB都是由VCA這樣一個控制器控制的。包括ViewA和ViewB上面數據的請求、數據的處理、界面交互的處理等等事宜,都是由VCA控制器來處理。這樣的話,勢必造成VCA代碼比較混亂,不方便管理。
第二種方式:如上圖所示,讓ViewA有自己的控制器VCA、ViewB也有自己的控制器VCB,讓ViewB放置在ViewA上面就行了。只是在這個過程中,不能簡單的只調用addSubView:方法,還有使用addChildViewController:方法。
蘋果官方的解釋:
蘋果新的API增加了addChildViewController方法,並且希望我們在使用addSubview時,同時調用[self addChildViewController:child]方法將subview對應的viewController也加到當前ViewController的管理中。
對於那些當前暫時不需要顯示的subview,只通過addChildViewController把subViewController加進去;需要顯示時再調用transitionFromViewController方法。將其添加進入底層的ViewController中。
這樣做的好處:
1.無疑,對頁面中的邏輯更加分明了。相應的View對應相應的ViewController。
2.當某個子View沒有顯示時,將不會被Load,減少了內存的使用。
3.當內存緊張時,沒有Load的View將被首先釋放,優化了程序的內存釋放機制。
然后這里就涉及到addChildViewController等方法的使用,網上對它的介紹內容比較繁多,總結起來其實也就是下面這個代碼,使用的時候照搬即可:
if (添加controller控制器) { [self addChildViewController:controller]; [controller didMoveToParentViewController:self]; } else {// 刪除controller控制器 [controller willMoveToParentViewController:nil]; [controller removeFromParentViewController]; }
現在直接給出,完成項目要求的相關代碼:(不能直接使用,主要是看方法)
@property (nonatomic, strong) UISegmentedControl *segmentedControl; @property (nonatomic, strong) WSFShopActivityListVC *shopActivityListVC; - (UISegmentedControl *)segmentedControl { if (!_segmentedControl) { _segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"空間",@"活動"]]; _segmentedControl.frame = CGRectMake(0, 0, 140, 32); _segmentedControl.selectedSegmentIndex = 0; _segmentedControl.tintColor = [UIColor whiteColor]; _segmentedControl.layer.cornerRadius = 16; _segmentedControl.layer.masksToBounds = YES; _segmentedControl.layer.borderWidth = 1; _segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor; [_segmentedControl addTarget:self action:@selector(indexDidChangeForSegmentedControl:) forControlEvents:UIControlEventValueChanged]; } return _segmentedControl; } - (WSFShopActivityListVC *)shopActivityListVC { if (!_shopActivityListVC) { _shopActivityListVC = [[WSFShopActivityListVC alloc] init]; } return _shopActivityListVC; } #pragma mark - UISegmentedControl協議方法 - (void)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender { switch(sender.selectedSegmentIndex){ case 0: sender.selectedSegmentIndex = 0; [self.shopActivityListVC.view removeFromSuperview]; [self.shopActivityListVC willMoveToParentViewController:nil]; [self.shopActivityListVC removeFromParentViewController]; break; case 1: sender.selectedSegmentIndex = 1; [self.view addSubview:self.shopActivityListVC.view]; [self addChildViewController:self.shopActivityListVC]; [self.shopActivityListVC didMoveToParentViewController:self]; break; default: break; } }
第三種實現方式:如上圖所示,VCC專門作為一個控制器容器,輪流着將ViewA和ViewB添加到ViewC上面。
當然,還可以將前面兩種思路綜合起來使用,思路如下圖:
第四種方式:如上如所示,使用了另外一個“專門的ViewController容器”VCC。結合第一種、第二種的思路應該是很好理解上圖的,這里就不多說了。
使用注意事項:
1、對於SKStoreProductViewController這類控制器,設計者只允許將它模態跳轉出來。此時使用addChildViewController是會報錯的。
具體使用可以參看這片文章【https://www.cnblogs.com/cchHers/p/9099421.html】。
最后對於 UISegmentedControl控件的各種屬性、各種方法的說明,我就先不往下寫了。以后有時間在更新~
~暫時就這么多內容了。