最終效果圖:
主控制器 BeyondViewController
繼承自UISplitViewController<喎?/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 SplitViewCtrl的Master主控制器, 繼承自表格控制器 FoodTypeListController 【菜系列表】及其代理 FoodListController SplitViewCtrl的從控制器,繼承自表格控制器 展示的是某一菜系下所有的菜【菜的列表】 WebView展示某一道 菜 的詳情 模型Model 封裝的一個Cell View
//
// 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 ()
//
// FoodTypeListController.h
// 27_SplitViewCtroller
//
// Created by beyond on 14-8-31.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// SplitViewCtrl的Master主控制器,繼承自表格控制器 【菜系列表】
#import
//
// 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
//
// FoodListController.h
// 27_SplitViewCtroller
//
// Created by beyond on 14-8-31.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// SplitViewCtrl的從控制器,繼承自表格控制器 某一菜系下所有的【菜的列表】
// 點擊左邊菜系列表控制器中的某一行時,本控制器將展示該菜系下的所有菜
#import
//
// 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 ()
//
// FoodDetailController.h
// 27_SplitViewCtroller
//
// Created by beyond on 14-8-31.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// 點擊菜列表控制中的某一行,來到這,顯示該道菜的詳細信息,直接用webView展示
#import
//
// 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
//
// Food.h
// 27_SplitViewCtroller
//
// Created by beyond on 14-8-31.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// 模型:一種菜肴 Food 對應plist文件裡面的一個字典
#import
//
// FoodType.h
// 27_SplitViewCtroller
//
// Created by beyond on 14-8-31.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// 模型:一種菜系 FoodType 對應plist文件裡面的一個字典
#import
//
// 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
//
// 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