标签:uisplitviewcontrolle ipad delegate webview
最终效果图:

主控制器 BeyondViewController
继承自UISplitViewController
// // BeyondViewController.h // 27_SplitViewCtroller // // Created by beyond on 14-8-31. // Copyright (c) 2014年 com.beyond. All rights reserved. // 主控制器,继承自UISplitViewController,左边master控制器是:FoodTypeListCtrl,右边的从控制器是FoodListCtrl #import <UIKit/UIKit.h> @interface BeyondViewController : UISplitViewController @end
//
// 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
SplitViewCtrl的Master主控制器,
继承自表格控制器
FoodTypeListController 【菜系列表】及其代理
// // 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
//
// 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
// // 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
FoodListController
SplitViewCtrl的从控制器,继承自表格控制器
展示的是某一菜系下所有的菜【菜的列表】
// // 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
//
// 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
WebView展示某一道 菜 的详情
// // 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
//
// 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
// // 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
// // 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
封装的一个Cell View
// // 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
//
// 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
iOS_27SplitViewController的简单使用
标签:uisplitviewcontrolle ipad delegate webview
原文地址:http://blog.csdn.net/pre_eminent/article/details/38982705