SplitViewController的简单使用

最终效果图:

\

\

 

主控制器 BeyondViewController 

继承自UISplitViewController<喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">// // BeyondViewController.h // 27_SplitViewCtroller // // Created by beyond on 14-8-31. // Copyright (c) 2014年 com.beyond. All rights reserved. // 主控制器,继承自UISplitViewController,左边master控制器是:FoodTypeListCtrl,右边的从控制器是FoodListCtrl #import @interface BeyondViewController : UISplitViewController @end 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//
//  BeyondViewController.m
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  主控制器,继承自UISplitViewController,左边master控制器是:FoodTypeListCtrl,右边的从控制器是FoodListCtrl
 
# import "BeyondViewController.h"
// 菜系 列表 控制器
# import "FoodTypeListController.h"
// 菜列表 控制器
# import "FoodListController.h"
 
// 菜系 列表 控制器 定义的协议,目的是:点击了菜系 列表 中的某一行时,告诉代理(即菜列表控制器) 要展示哪一种菜系下面的所有菜
# import "FoodTypeListCtrlDelegate.h"
 
@interface BeyondViewController () <foodtypelistctrldelegate>
 
 
@end
 
@implementation BeyondViewController
// 重要~~~主控制器充当中间人,先得到FoodTypeListController,并且成为它的代理,得到菜系 列表 的某一行被点击时 对应的菜系对象
//  然后再在FoodTypeListController的代理方法中,得到FoodListController,并将菜系 进一步传递给FoodListController
- ( void )viewDidLoad
{
     [ super viewDidLoad];
     // 1.先得到Master控制器,即导航控制器,再从导航控制器中得到  FoodTypeListController,并且成为它的代理
     UINavigationController *foodTypeListNav = [self.childViewControllers firstObject];
     FoodTypeListController *foodTypeListCtrl = [foodTypeListNav.childViewControllers firstObject];
     foodTypeListCtrl.delegate = self;
     
     
     
     // 让foodListCtrl成为主控制器的代理,仅仅是监听Master控制器的出现和隐藏,并在foodListCtrl的左按钮上显示相应的提示文字(点击该文字可以展开被隐藏的Master控制器)
     UINavigationController *foodListNav = [self.childViewControllers lastObject];
     FoodListController<uisplitviewcontrollerdelegate> *foodListCtrl = [foodListNav.childViewControllers firstObject];
     self.delegate = foodListCtrl;
}
// 2. 然后再在FoodTypeListController的代理方法中,得到FoodListController,并将菜系 进一步传递给FoodListController
- ( void )foodTypeListController:(FoodTypeListController *)foodTypesVc didSelectedFoodType:(FoodType *)type
{
     UINavigationController *foodListNavi = [self.childViewControllers lastObject];
     FoodListController *foodListCtrl = [foodListNavi.childViewControllers firstObject];
     foodListCtrl.foodType = type;
     
     [foodListNavi popToRootViewControllerAnimated:YES];
}
 
@end
</uisplitviewcontrollerdelegate></foodtypelistctrldelegate>



 

 

 

SplitViewCtrl的Master主控制器,

继承自表格控制器 

FoodTypeListController 【菜系列表】及其代理

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
//  FoodTypeListController.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  SplitViewCtrl的Master主控制器,继承自表格控制器 【菜系列表】
 
# import <uikit uikit.h= "" >
@protocol FoodTypeListCtrlDelegate;
@interface FoodTypeListController : UITableViewController
 
 
// 成员:代理,当点击了某一行时,告诉代理 即点击了哪一种菜系,从而,右边的控制器展示相应的菜名列表
@property (weak, nonatomic) id<foodtypelistctrldelegate> delegate;
 
 
@end
</foodtypelistctrldelegate></uikit>

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//
//  FoodTypeListController.m
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
 
# import "FoodTypeListController.h"
 
# import "FoodType.h"
 
# import "FoodTypeListCtrlDelegate.h"
@interface FoodTypeListController ()
// 成员:数组,保存着从plist中加载的所有的从字典一一转成对象的FoodType
@property (strong, nonatomic) NSArray *foodTypesArr;
@end
 
@implementation FoodTypeListController
// getter访问时才加载,懒加载
- (NSArray *)foodTypesArr
{
     if (_foodTypesArr == nil) {
         // 经典,一句话将参数所对应的Plist文件中的字典数组,转成 该类的对象数组
         _foodTypesArr = [FoodType objArrFromPlistName:@ "food_types.plist" ];
     }
     return _foodTypesArr;
}
 
- ( void )viewDidLoad
{
     [ super viewDidLoad];
     
     self.title = @ "菜系" ;
     // 默认选择第0行,调用自己的方法,给其传递数据模型
     [self.tableView selectRowAtIndexPath:kIndexPathZero animated:YES scrollPosition:UITableViewScrollPositionTop];
     // 让第0行,显示选中状态,需配合覆盖掉系统默认的方法:viewWillAppear
     [self tableView:self.tableView didSelectRowAtIndexPath:kIndexPathZero];
}
// 取消系统默认的一些 事件,让第0行,显示选中状态
- ( void )viewWillAppear:(BOOL)animated
{
  // do nothing...
}
 
#pragma mark - 数据源方法
// 多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return self.foodTypesArr.count;
}
// 每行显示的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *ID = @ "FoodType" ;
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
     if (cell == nil) {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
     }
     // 模型数组中取出对应行的模型
     FoodType *type = self.foodTypesArr[indexPath.row];
     // 设置独一无二的内容
     cell.textLabel.text = type.name;
     // 返回cell
     return cell;
}
#pragma mark - 代理方法
- ( void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     // 如果 代理(就是右边的从控制器)需要,才告知 当前选择了哪一个菜系
     if ([self.delegate respondsToSelector: @selector (foodTypeListController:didSelectedFoodType:)]) {
         FoodType *type = self.foodTypesArr[indexPath.row];
         [self.delegate foodTypeListController:self didSelectedFoodType:type];
     }
}
 
 
@end


定义好的协议

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
//  FoodTypeListCtrlDelegate.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
 
# import <foundation foundation.h= "" >
@class FoodType;
@protocol FoodTypeListCtrlDelegate <nsobject>
 
 
@optional
// 当点击了某一行时,告诉代理 即点击了哪一种菜系,从而,右边的控制器展示相应的菜名列表
- ( void )foodTypeListController:(FoodTypeListController *)ctrl didSelectedFoodType:(FoodType *)foodType;
 
 
@end
</nsobject></foundation>



 

 

FoodListController

 

SplitViewCtrl的从控制器,继承自表格控制器 

展示的是某一菜系下所有的菜【菜的列表】

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
//  FoodListController.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  SplitViewCtrl的从控制器,继承自表格控制器  某一菜系下所有的【菜的列表】
//  点击左边菜系列表控制器中的某一行时,本控制器将展示该菜系下的所有菜
 
# import <uikit uikit.h= "" >
@class FoodType;
@interface FoodListController : UITableViewController
 
// 数据源,根据传入的菜系,通过它的idstr,拼凑出新的plist名称,加载,转成Food模型对象数组
@property (strong, nonatomic) FoodType *foodType;
@end
</uikit>

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//
//  FoodListController.m
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
 
# import "FoodListController.h"
 
# import "FoodDetailController.h"
# import "Food.h"
# import "FoodCell.h"
# import "FoodType.h"
 
// 成为UISplitViewControllerDelegate的代理,目的是监听其显示和隐藏方法,从而控制leftBarButtonItem的显示和隐藏
@interface FoodListController ()<uisplitviewcontrollerdelegate>
@property (strong, nonatomic) NSArray *foodsArr;
@end
 
@implementation FoodListController
 
- ( void )viewDidLoad
{
     [ super viewDidLoad];
     
}
 
// 重要~~~拦截setterFoodType方法,设置标题,从对应的Plist加载数据,并转成对象数组,刷新表格
- ( void )setFoodType:(FoodType *)foodType
{
     _foodType = foodType;
     
     NSString *filename = [NSString stringWithFormat:@ "type_%@_foods.plist" , foodType.idstr];
     // 经典,一句话将参数所对应的Plist文件中的字典数组,转成 该类的对象数组
     self.foodsArr = [Food objArrFromPlistName:filename];
     self.title = foodType.name;
     if (self.isViewLoaded) {
         // 默认让tableView 滚动到第 0 行
         [self.tableView scrollToRowAtIndexPath:kIndexPathZero atScrollPosition:UITableViewScrollPositionTop animated:YES];
         // 刷新表格
         [self.tableView reloadData];
     }
}
#pragma mark - SplitViewCtrl的代理方法
// 即将显示 Master主控制器
- ( void )splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
     self.navigationItem.leftBarButtonItem = nil;
}
// 即将隐藏 Master主控制器
- ( void )splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc
{
     barButtonItem.title = @ "菜系" ;
     self.navigationItem.leftBarButtonItem = barButtonItem;
}
 
 
#pragma mark - 数据源方法
// 多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return self.foodsArr.count;
}
// 高度封装了FoodCell,控制器知道得很少
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     FoodCell *cell = [FoodCell cellWithTableView:tableView];
     
     cell.food = self.foodsArr[indexPath.row];
     
     return cell;
}
#pragma mark - 代理方法
// cell 行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     return 100 ;
}
// 选中某一行
- ( void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
     // 点击那行  对应的模型
     Food *food = self.foodsArr[indexPath.row];
     FoodDetailController *detailVc = [[FoodDetailController alloc] init];
     // 传递数据模型,内部会拦截
     detailVc.food = food;
     [self.navigationController pushViewController:detailVc animated:YES];
}
 
@end
</uisplitviewcontrollerdelegate>



WebView展示某一道 菜 的详情

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//
//  FoodDetailController.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  点击菜列表控制中的某一行,来到这,显示该道菜的详细信息,直接用webView展示
 
# import <uikit uikit.h= "" >
@class Food;
@interface FoodDetailController : UIViewController
 
// 数据源,要显示哪道菜
@property (strong, nonatomic) Food *food;
@end
</uikit>

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//
//  FoodDetailController.m
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  点击一行,来到这,显示该道菜的详细信息,直接用webView展示
 
# import "FoodDetailController.h"
# import "Food.h"
 
@interface FoodDetailController ()
@property (weak, nonatomic) UIWebView *webView;
@end
 
@implementation FoodDetailController
// 让weibView就是控制器的view
- ( void )loadView
{
     UIWebView *webView = [[UIWebView alloc] init];
     // bounds就是屏幕的全部区域,applicationFrame就是app显示的区域,不包含状态栏
     webView.frame = [UIScreen mainScreen].applicationFrame;
     // 随着屏幕的旋转,宽高自动伸缩
     webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
     self.view = webView;
     // 成员变量,记住,目的是 避免强转
     self.webView = webView;
}
 
- ( void )viewDidLoad
{
     [ super viewDidLoad];
     // 导航栏标题
     self.title = self.food.name;
     // 重点~~~拼接本地url,注意:如果在沙盒创建真实的文件夹,那么加载文件时,要加上文件夹名
     NSString *fileName = [NSString stringWithFormat:@ "Html/food/%@.html" , self.food.idstr];
     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:fileName  withExtension:nil]];
     [self.webView loadRequest:request];
}
@end



 

模型Model

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//
//  Food.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  模型:一种菜肴 Food 对应plist文件里面的一个字典
 
# import <foundation foundation.h= "" >
 
@interface Food : NSObject
 
// 必须与plist文件中 字典的key 一模一样
// id
@property (copy, nonatomic) NSString *idstr;
// 菜名
@property (copy, nonatomic) NSString *name;
// 小图标url
@property (copy, nonatomic) NSString *imageUrl;
// 网页的url
@property (copy, nonatomic) NSString *url;
// 本道菜预计耗时多长
@property (copy, nonatomic) NSString *time;
// 制作难度多大
@property (copy, nonatomic) NSString *diff;
 
@end
</foundation>



 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
//  FoodType.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  模型:一种菜系 FoodType 对应plist文件里面的一个字典
 
# import <foundation foundation.h= "" >
 
@interface FoodType : NSObject
// ID
@property (copy, nonatomic) NSString *idstr;
// 菜系 名称:如粤菜 川菜 家常菜
@property (copy, nonatomic) NSString *name;
 
@end
</foundation>



 

封装的一个Cell View

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//
//  FoodCell.h
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  自定义cell,一个cell 展示一个food模型里面的数据,传入tableView实例化cell的目的是封装得最彻底,让控制器作最少的事,知道得最少
 
# import <uikit uikit.h= "" >
@class Food;
@interface FoodCell : UITableViewCell
 
// 数据源模型,提供数据给内部的子控件们显示,内部会拦截setter方法
@property (strong, nonatomic) Food *food;
// 传入tableView实例化cell的目的是封装得最彻底,让控制器作最少的事,知道得最少
+ (instancetype)cellWithTableView:(UITableView *)tableView;
 
@end
</uikit>



 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//
//  FoodCell.m
//  27_SplitViewCtroller
//
//  Created by beyond on 14-8-31.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//
 
# import "FoodCell.h"
 
# import "Food.h"
# import "UIImageView+WebCache.h"
 
@interface FoodCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *descLabel;
@end
 
 
 
@implementation FoodCell
 
// 传入tableView实例化cell的目的是封装得最彻底,让控制器作最少的事,知道得最少
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
     // cellID必须和xib中的一模一样
     static NSString *cellID = @ "FoodCell" ;
     FoodCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
     if (cell == nil) {
         // 从xib创建
         cell = [[[NSBundle mainBundle] loadNibNamed:cellID owner:nil options:nil] lastObject];
         // 右边是箭头
         cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
     }
     return cell;
}
// 数据源模型,提供数据给内部的子控件们显示,内部会拦截setter方法
- ( void )setFood:(Food *)food
{
     _food = food;
     
     // 小图标
     [self.iconView setImageWithURL:[NSURL URLWithString:food.imageUrl] placeholderImage:[UIImage imageNamed:@ "timeline_image_placeholder" ]];
     // 菜名
     self.nameLabel.text = food.name;
     // 子标题
     self.descLabel.text = [NSString stringWithFormat:@ "难度:%@  时长:%@" , food.diff, food.time];
     
     
}
@end


XIB

 

 

转载于:https://www.cnblogs.com/YH-Coding/p/5331788.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值