本文将从头到尾讲述做iWatch 图片浏览,用到如下技术:
a.分页视图
b.控制器间的传值
c.字典转模型
d.业务逻辑的优化
e.模态展示
一、iWatch图片浏览效果图
图片浏览器是分页视图,当点击一个视图时,每显示每一个视图的详细信息。
图片浏览.gif
二、Storyboard 的操作
如下五个控制器(A、B、C、D、E控制器),都分别加载五个button ,其父类都是InterfaceController,如下图所示:
1.png
五个控制器的button连线新的控制器,model 展示。并在segue 加唯一标识,从0到4一个个增加。新的控制器的父类是DetailInterfaceController。
2.png
三、代码操作
1.代码目录结构如下
3.png
2.1 DetailModel.h文件代码如下
@interface DetailModel : NSObject
//城市
@property (nonatomic, copy) NSString *city;
//类型
@property (nonatomic, strong) NSString *type;
//姓名
@property (nonatomic, copy) NSString *name;
+(NSArray<DetailModel*>*)loadDatas;
@end
2.2 DetailModel.m文件代码如下
@implementation DetailModel
+(NSArray<DetailModel*>*)loadDatas
{
//得到路径
NSString *url = [[NSBundle mainBundle] pathForResource:@"data.plist" ofType:nil];
//得到字典数组
NSArray *arr = [NSArray arrayWithContentsOfFile:url];
NSMutableArray<DetailModel *> * mArr = [NSMutableArray array];
//字典转模型
for (NSDictionary *dict in arr)
{
DetailModel *model = [[DetailModel alloc] init];
[model setValuesForKeysWithDictionary:dict];
[mArr addObject:model];
}
return mArr;
}
//解决 字典值多,模型属性少,崩溃问题
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
@end
3.0 InterfaceController.m文件代码如下
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
//加载数据
self.datas = [DetailModel loadDatas];
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
#pragma mark - 通过 segue 进行跳转会走此方法
-(id)contextForSegueWithIdentifier:(NSString *)segueIdentifier
{
//传递模型过去
NSInteger index = [segueIdentifier integerValue];
return _datas[index];
}
@end
4.0 DetailInterfaceController.m文件代码如下
@interface DetailInterfaceController()
//姓名
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *nameLabel;
//职业
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *typeLabel;
//城市
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceLabel *cityLabel;
@end
@implementation DetailInterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
//将上一个控制器传来的模型 进行转型
DetailModel *model = context;
//给label 赋值
[self.nameLabel setText:model.name];
[self.typeLabel setText:model.type];
[self.cityLabel setText:model.city];
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
@end
四、代码优化
如果分页视图,有100页呢,难道在Storyboard中加载100个控制器吗?如何优化呢?
如下优化的部分#import "InterfaceController.h",主要用通过reloadRootControllersWithNames方法,在程序启动的时候,设置storyboard name 和context,这样子可以设置多个分页控制器,分页控制器的个数由于数据源的改变而改变,如此轻松,如此easy!!
@interface InterfaceController()
//数据
@property (nonatomic, strong) NSArray<DetailModel*> *datas;
//背景btn
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceButton *backGroundBtn;
//记录当前那个modal,传给detail控制器
@property (nonatomic, strong) DetailModel *model;
@end
@implementation InterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
//加载数据
self.datas = [DetailModel loadDatas];
//若context 为nil时说时控制器没有加载
if (context == nil)
{
//定义两个数组,分别存放下文和storyboard name
NSString *storyBoardName = @"InterfaceController";
NSMutableArray *SBNameArr = [NSMutableArray array];
NSMutableArray *indexArr = [NSMutableArray array];
for (int i = 0 ; i < _datas.count; i++) {
[SBNameArr addObject:storyBoardName];
DetailModel *model = _datas[i];
[indexArr addObject:model];
}
//将名字和内容给控制器
[WKInterfaceController reloadRootControllersWithNames:SBNameArr contexts:indexArr];
}else{
//如果有内容的话,就加载其自己图片
self.model = context;
[self.backGroundBtn setBackgroundImageNamed:_model.photo_name];
}
}
#pragma mark - 通过 segue 进行跳转会走此方法
-(id)contextForSegueWithIdentifier:(NSString *)segueIdentifier
{
//传递模型过去
return _model;
}
Over !! Thank you a l
网友评论