前言
最近公司需要開發(fā)iPad版的應(yīng)用程序,項目中要實現(xiàn)分屏控制器的功能,之前有了解到使用UISplitViewController可以實現(xiàn)分屏的功能,當(dāng)時查了查資料,感覺挺簡單的,但是隨著研究的深入,發(fā)現(xiàn)并不是那么容易的,由于網(wǎng)上關(guān)于UISplitViewController的使用教程并不多,自定義實現(xiàn)分屏功能的教程就更少了,所以接下來我將把這幾天對UISplitViewController的研究和自定義實現(xiàn)分屏控制器的功能的Demo分享給大家,希望能幫助到有這方面困惑的朋友。
使用系統(tǒng)的UISplitViewController
Demo中的第一個target是使用的UISplitViewController,通過storyboard實現(xiàn),系統(tǒng)的UISplitViewController挺簡單的,實現(xiàn)步驟:
- 在storyboard中添加一個UISplitViewController控制器,給DetailViewController包裝一個導(dǎo)航控制器,這里在連線的時候要注意,要和splitViewController建立關(guān)系,選擇detail view controller。
2.新建一個控制器MainViewController繼承自UISplitViewController,MasterTableViewController繼承自UITableViewController,DetailViewController繼承自UIViewController,并把相關(guān)控制器和storyboard中的相關(guān)聯(lián)益眉。
3.在MasterTableViewController中編寫一個協(xié)議,主要思路就是MainViewController成為MasterTableViewController的代理,實現(xiàn)協(xié)議方法,從而和DetailViewController交互雹熬。
@protocol masterTableViewControllerDelegate <NSObject>
- (void)masterTableViewController:(MasterTableViewController *)masterVC didSelectedRow:(SingleModel *)singleModel;
@end
在MasterTableViewController中的tableView行點擊事件中,調(diào)用代理方法,傳遞數(shù)據(jù)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if ([self.delegate respondsToSelector:@selector(masterTableViewController:didSelectedRow:)]) {
GroupModel *groupModel = self.groupModel[indexPath.section];
[self.delegate masterTableViewController:self didSelectedRow:groupModel.typeList[indexPath.row]];
}
}
在MainViewController中,設(shè)置當(dāng)前控制器為MasterTableViewController的代理,實現(xiàn)協(xié)議方法
- (void)viewDidLoad {
[super viewDidLoad];
//獲取到導(dǎo)航控制器對象
UINavigationController *masterNav = [self.childViewControllers firstObject];
//獲取到MasterTableViewController的對象
MasterTableViewController *master = [masterNav.childViewControllers firstObject];
master.delegate = self;
}
/**
* masterTableViewController的代理方法
*/
- (void)masterTableViewController:(MasterTableViewController *)masterVC didSelectedRow:(SingleModel *)singleModel{
UINavigationController *detailNav = [self.childViewControllers lastObject];
DetailViewController *detail = [detailNav.childViewControllers firstObject];
detail.singleModel = singleModel;
[detailNav popToRootViewControllerAnimated:YES];
}
重寫DetailViewController的屬性singleModel的setter方法就能實現(xiàn)和MasterTableViewController交互了
- (void)setSingleModel:(SingleModel *)singleModel{
_singleModel = singleModel;
self.nameView.text = singleModel.subjectName;
}
通常情況下,詳情界面也會是一個tableView,在重寫的singleModel中獲取到上一界面?zhèn)鱽淼闹?讓當(dāng)前控制器的tableView reloadData就可以了碳抄。
自定義實現(xiàn)分屏的功能
這個是今天要介紹的重點,因為有的時候系統(tǒng)的UISplitViewController并不能滿足項目的需求,UISplitViewController只能做為程序窗口的根視圖,當(dāng)程序中需要使用UITabBarController或者UINavigationController來切換到分屏控制器的時候,并不能到達(dá)我們的目的是牢。
可以看一下官網(wǎng)對UISplitViewController的介紹
主要的一個截圖
大體的意思就是分屏控制器不能進(jìn)入導(dǎo)航的棧中(也就是不能通過導(dǎo)航控制器跳轉(zhuǎn)),不推薦將分屏控制器做為某個控制器的子控制器,通常是做為程序窗口的根視圖痴荐。
那如果需求是: 在主界面需要跳轉(zhuǎn)到分屏控制器改怎么辦呢烘豌?
這里有一種思路就是在主界面放一個按鈕,在按鈕的點擊方法里面切換window的根視圖。這個不是今天介紹的重點,就不在這里討論了辙纬。
重點是---怎么自定義控制器具有分屏顯示的功能(結(jié)合UITabBarController)
思路是新建三個控制器,分別是主控制器豁遭、左側(cè)顯示的列表控制器和右側(cè)顯示的詳情控制器,將列表控制器和詳情控制器的View添加到主控制器的View上,讓主控制器成為列表控制器的代理,實現(xiàn)相應(yīng)的協(xié)議方法從而和詳情控制器就行交互。大體的思路和上面提到的使用系統(tǒng)的UISplitViewController差不多贺拣,主要的不同就是沒有使用UISplitViewController,而是自定義的UIViewController,主要看一下自定義控制器中的代碼蓖谢。
添加兩個導(dǎo)航控制器的屬性
@property (nonatomic, strong) UINavigationController *masterNav;
@property (nonatomic, strong) UINavigationController *detailNav;
在viewDidLoad中初始化列表控制器和詳情控制器,并添加到主控制界面上捂蕴。
- (void)viewDidLoad {
[super viewDidLoad];
// self.navigationController.navigationBarHidden = YES;
HZYMasterViewController *masterVC = [HZYMasterViewController new];
self.masterNav = [[UINavigationController alloc] initWithRootViewController:masterVC];
[self addChildViewController:self.masterNav];
[self.view addSubview:self.masterNav.view];
HZYDetailViewController *detailVC = [HZYDetailViewController new];
self.detailNav = [[UINavigationController alloc] initWithRootViewController:detailVC];
[self addChildViewController:self.detailNav];
[self.view addSubview:self.detailNav.view];
masterVC.delegate = self;
}
實現(xiàn)協(xié)議方法
- (void)masterViewController:(HZYMasterViewController *)masterVC didSelectedRowInSection:(NSInteger)section{
HZYDetailViewController *detailVC = [self.detailNav.childViewControllers firstObject];
[self.detailNav popToRootViewControllerAnimated:YES];
//向detailVC傳遞點擊的Section用來區(qū)分detailVC中tableViewCell的顯示樣式
[detailVC putSection:section];
}
核心的方法,當(dāng)控制器的View的子視圖重新布局時調(diào)用,用來布局子視圖。
- (void)viewWillLayoutSubviews{
[_masterNav.view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(@64);
make.left.equalTo(@70);
make.width.equalTo(kMasterWidth);
make.bottom.equalTo(@0);
}];
[_detailNav.view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.equalTo(_masterNav.view);
make.right.equalTo(self.view.mas_right);
make.left.equalTo(_masterNav.view.mas_right);
}];
}
DetailViewController在putSection方法的實現(xiàn)中獲得index,工具類通過index獲得相應(yīng)模型數(shù)據(jù),刷新tableView
- (void)putSection:(NSInteger)section{
_section = section;
__weak typeof (self) weakSelf = self;
//獲取點擊Section的模型數(shù)據(jù)闪幽,為了方便這里每個Section中的行都是一個模型數(shù)據(jù)啥辨,如果獲取網(wǎng)絡(luò)數(shù)據(jù)的話要更改工具類中的方法,視情況而定盯腌!
[Tool getDataWithSection:section successBlock:^(NSMutableArray *modelArray) {
weakSelf.modelArray = modelArray;
[weakSelf.tableView reloadData];
}];
}
Demo介紹
Demo分為兩個target,一個是通過系統(tǒng)UISplitViewController結(jié)合storyboard實現(xiàn)的,一個是自定義控制器純代碼實現(xiàn)的溉知。
工程中添加兩個target的遇到的坑
之前并沒有在一個工程中添加過兩個target,這次在兩個target下coding遇到最多的問題就是
一般這種問題就是編譯的問題,找不到編譯的源文件,解決方法就是在工程的target->Build Phases->Compile Sources,添加報錯的.m文件,重新編譯就OK了!
為什么會產(chǎn)生這種錯誤呢腕够?主要就是在新建類的時候沒有選中相應(yīng)的target
還有一種解決方案级乍,選中報錯的.m文件,展開實用工具(配合IB實用的那個欄目),點擊第一個(file inspector),找到下面的Target Membership,勾選上相應(yīng)的target。
結(jié)語:
第一次在簡書上面發(fā)表文章,希望我這幾天的研究能夠幫助到有這方面困惑的朋友,謝謝大家的支持帚湘。
最近很欣賞薛之謙說的一句話:在這個時代根本就沒有懷才不遇玫荣, 關(guān)鍵是你真的必須具備才華 所以請你一定要強(qiáng)大自己!對于我們iOS開發(fā)來說大诸,市場已經(jīng)進(jìn)入飽和期了(甚至有人調(diào)侃為iOS爛大街)捅厂,很多人抱怨工作不好找,現(xiàn)在的市場需要的不再是只會寫寫界面底挫,只會上網(wǎng)復(fù)制粘貼代碼的開發(fā)者恒傻,所以你一定要強(qiáng)大自己脸侥,等你足夠強(qiáng)大了建邓,好的工作自然就來了!