小记:iOS 中一般对于 view 不依赖 model 的的两种代码书写形式
一. 前言
对于在 MVC 的定义中,view 层是不引用 model 层,view 和 model 是不相往来的
一般开发中,我们都写过 在自定义 view 中增加一个 model 的属性,外接直接传个 model 来,在 view 中 model 的 set 方法里对 view 的控件赋值的代码,例如在自定义 UITableViewCell 时用的很多,此时 view 是直接引用了 model
基于封装的思想,我们需要竟可能的复用我们的代码,复用我们的 view,这时我们需要进行解耦,不依赖于某个特殊的 model。另外,如果对于很特殊的 view,整个项目中没有什么重用的,可以按之前情况处理
本文简要介绍自己常用的两种写法来解耦 view 和 model,使之更符合 MVC 的定义
二.定义 ViewModel 对象及 ViewModelType (协议) 的形式
- 说明
- 将 view 中所有控件需要的数据依次列出
- 定义 ViewModelType 一种协议,定义协议方法 ,旨在通过协议方法,返回 view 需要的数据
- view 中控件赋值,需要外接传入遵守 ViewModelType 协议的 ViewModel,在 ViewModel 的 set 方法里进行控件赋值
- 该 ViewModel 的创建是依赖具体的 model 的,需要遵守 ViewModelType 协议
- view 和 ViewModelType 为一整体,通过更换不同的 ViewModel 来达到重用。更换不同 ViewModel,也相当于更换了数据 model。
- 示例
- 如一个 cell (有大标题,几个子标题和标题对应的内容,状态,图片等)
@interface LXReservationCell : UITableViewCell @property (nonatomic, weak) id<LXReservationCellViewModelType> viewModel; @end
- LXReservationCellViewModelType 协议
@protocol LXReservationCellViewModelType <NSObject> // 标题
@property (nonatomic, copy, readonly) NSString *title;
// 第一个子标题
@property (nonatomic, copy, readonly) NSString *firstItemTitle;
// 第一个子标题对应的内容
@property (nonatomic, copy, readonly) NSString *firstItemContent; @end
- LXReservationCellViewModel 中
#import <Foundation/Foundation.h> @class LXReservationItem; @interface LXReservationCellViewModel : NSObject - (instancetype)initWithItem:(LXReservationItem *)item; @end
@interface LXReservationCellViewModel () <LXReservationCellViewModelType>
// 标题
@property (nonatomic, copy) NSString *title;
// 第一个子标题
@property (nonatomic, copy) NSString *firstItemTitle;
// 第一个子标题对应的内容
@property (nonatomic, copy) NSString *firstItemContent;
@end
@implementation LXReservationCellViewModel - (instancetype)initWithItem:(LXReservationItem *)item {
if (self = [super init]) {
self.title = item.title;
self.firstItemTitle = item.orderCategory;
self.firstItemContent = item.orderdate; }
return self; }
- 如一个 cell (有大标题,几个子标题和标题对应的内容,状态,图片等)
三、定义 view 对应的 config,使用链式编程的形式进行对 view 控件赋值
- 说明
- 将 view 中所有控件需要的数据依次列出
- 定义一个 config 对象,使用链式编程的形式进行获取 view 需要的各种数据,在 config 中弱引用 view,把各种数据在赋值给 view
- view 中需要定义一个配置数据的方法,方法的参数是个 block,block 传一个 config 对象给外界使用
- view 和 config 为一整体,并不引用 model,因此脱离的 model 的限制,具有重用性
- 示例
- 如一个简单的展示标题、内容,还有一个按钮的 view
#import <UIKit/UIKit.h> @class LXIntroduceViewConfig; @interface LXIntroduceView : UIView
// 标题
@property (nonatomic, copy) NSString *title;
// 内容
@property (nonatomic, copy) NSString *content;
// 按钮标题
@property (nonatomic, copy) NSString *btnTitle; // 配置 view 对应的数据的方法
- (void)lx_makeWithConfig:(void(^)(LXIntroduceViewConfig *config))block;
- (void)lx_makeWithConfig:(void (^)(LXIntroduceViewConfig *))block {
LXIntroduceViewConfig *config = [[LXIntroduceViewConfig alloc]initWithIntroduceView:self];
!block? : block(config);
}
- LXIntroduceViewConfig.h
#import <Foundation/Foundation.h> @class LXIntroduceView; @interface LXIntroduceViewConfig : NSObject - (instancetype)initWithIntroduceView:(LXIntroduceView *)introduceView;
// 设置标题
- (LXIntroduceViewConfig *(^)(NSString *))setupTitle;
// 设置要显示的内容
- (LXIntroduceViewConfig *(^)(NSString *))setupContent;
// 设置按钮的标题
- (LXIntroduceViewConfig *(^)(NSString *))setupBtnTitle; @end
- LXIntroduceViewConfig.m
@interface LXIntroduceViewConfig ()
// 弱引用 view
@property (nonatomic, weak) LXIntroduceView *introduceView;
@end @implementation LXIntroduceViewConfig
// init
- (instancetype)initWithIntroduceView:(LXIntroduceView *)introduceView {
if (self = [super init]) {
self.introduceView = introduceView;
}
return self;
}
// 把标题传给 view,view 中 set 方法接收
- (LXIntroduceViewConfig *(^)(NSString *))setupTitle {
return ^(NSString *tmp) {
self.introduceView.title = tmp;
return self;
};
}
// 把内容传给 view,view 中 set 方法接收
- (LXIntroduceViewConfig *(^)(NSString *))setupContent {
return ^(NSString *tmp) {
self.introduceView.content = tmp;
return self;
};
}
// 把按钮标题传给 view
- (LXIntroduceViewConfig *(^)(NSString *))setupBtnTitle {
return ^(NSString *tmp) {
self.introduceView.btnTitle = tmp;
return self;
};
}
@end
- 外界使用
LXIntroduceView *introduceView = [[LXIntroduceView alloc]init];
[introduceView lx_makeWithConfig:^(LXIntroduceViewConfig *config) {
config
.setupTitle(self.resultItem.title)
.setupContent(self.resultItem.content)
.setupBtnTitle(@"test");
}];
- 如一个简单的展示标题、内容,还有一个按钮的 view
四. 结尾
- 一点一滴,仅此记录。
小记:iOS 中一般对于 view 不依赖 model 的的两种代码书写形式的更多相关文章
- vs中发布WebSever时启用HTTP-POST和HTTP-GET这两种协议
一.问题介绍 在vs中建立一个websever项目时候默认是禁用HTTP-POST和HTTP-GET这两种协议的.但是如果你是在本机上去调试或者是在iis中浏览都会有HTTP-POST这种方式,因为这 ...
- Android代码中设置字体大小,字体颜色,显示两种颜色.倒计时效果
Android代码中设置字体大小,字体颜色,显示两种颜色 在xml文件中字体大小用的像素 <TextView android:id="@+id/uppaid_time" an ...
- 【Java面试真题】剑指Offer53.2——0~n-1中缺失的数字(异或、二分两种解法)
[Java实现]剑指Offer53.2--0~n-1中缺失的数字:面试真题,两种思路分享 前面有另一道面试题[Java实现]剑指offer53.1--在排序数组中查找数字(LeetCode34:在排序 ...
- WebGIS中解决使用Lucene进行兴趣点搜索排序的两种思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 目前跟信息采集相关的一个项目提出了这样的一个需求:中国银行等 ...
- 关于实现自定义Dialog和实现Dialog里view的事件监听的两种方法
一.自定义dialog. 二.实现dialog里view的事件监听 1.自定义dialog比较简单.在实例化new的时候,加入样式,布局就行了.或者重写dialog. 2.实现dialog里view的 ...
- 用Java集合中的Collections.sort方法对list排序的两种方法
用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- 【转】java中byte数组与int类型的转换(两种方式)----不错
原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...
- springMVC中对HTTP请求form data和request payload两种数据发送块的后台接收方式
最近在做项目中发现,前台提交数据时,如果通过form表单提交和ajax发送json时,springMVC后台接收不能都通过@ModelAttribute方式处理,经过一番查找后,ajax发送json请 ...
- iOS同一项目多个Target的快速实现方法 - 两种使用场景详解
我们项目中,默认建好是只有一个target的,但是,一些场景中,多target能帮助我们更好的使用项目. 场景1: 同一项目,一般会分不同环境:开发环境.测试环境.正式(生产)环境. 这就涉及到一个请 ...
随机推荐
- C# Object reference not set to an instance of an object.
一.问题 Object reference not set to an instance of an object. (你调用的对象是空的) 二.解决问题 在使用 c# 的查询时,先筛选后在关联其他表 ...
- luogu3224 永无乡(动态开点,权值线段树合并)
luogu3224 永无乡(动态开点,权值线段树合并) 永无乡包含 n 座岛,编号从 1 到 n ,每座岛都有自己的独一无二的重要度,按照重要度可以将这 n 座岛排名,名次用 1 到 n 来表示.某些 ...
- springboot jpa mongodb 多条件分页查询
public Page<Recorded> getRecordeds(Integer page, Integer size, Recorded recorded) { if (page&l ...
- ios开发 xcode6以上安装Alcatraz管理插件
在终端上输入如下命令即可完成安装: curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | ...
- 算法学习分析-点分治 HDU 6269 Master of Subgraph
首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...
- webpack坑系列--安装webpack-cli
综下所述: 还是装3.11.0版本吧 cnpm i webpack@3.11.0 -D 最近在学习webpack过程中,根据官方文档推荐局部安装webpack,执行webpack -h命令出现以下提示 ...
- 谈谈python修饰器
前言 对python的修饰器的理解一直停留在"使用修饰器把函数注册为事件的处理程序"的层次,也是一知半解:这样拖着不是办法,索性今天好好整理一下关于python修饰器的概念及用法. ...
- 6、kvm克隆虚拟机
kvm克隆有两种方法可以使用先暂停kvm虚拟机 virsh suspend privi-server 方法一:对虚拟机本身直接clone virt-clone -o privi-server -n p ...
- c#文件相关笔记
1.将*.txt文件内容转换为一个字符串str FileStream fs = new FileStream("路径\\*.txt", FileMode.Open); Stream ...
- CXF 发布rest服务
1.1 什么是rest服务 REST 是一种软件架构模式,只是一种风格,rest服务采用HTTP 做传输协议,REST 对于HTTP 的利用实现精确的资源定位. Rest要求对资源定位更加准 ...