(iOS版)我是怎么设计带有增改查的表单

首先可以定义一个枚举

typedef enum{
ViewStatusEdit =1,
ViewStatusRetrieve =2,
ViewStatusNew =3//外面调用的时候,可以只设置edit就行
}ViewStatus;

这个用来标示当前表单处于一个什么样的状态。考虑到新增跟修改外面要加一个区分比较麻烦,那么可以把这个封装在里面,外面调的时候只要告诉表单处于编辑状态即可。例如:

//判断是编辑还是新增

if([NSString isBlankString: _newModel.id]){//只要id为空,那么肯定是新增
_viewStatus = ViewStatusNew;
}

newModel为表单要转换的一个实体,表单要显示的数据都在这个model里面,要提交的信息也都在这里,所以可以假设model张这样:

@interface Model :NSObject
@property(nonatomic, copy) NSString *token;
@property(nonatomic, copy) NSString *id;
@property(nonatomic, copy) NSString *type;
@property(nonatomic, copy) NSString *date;
@property(nonatomic, copy) NSString *time;
@property(assign, nonatomic)float data;
@property(nonatomic, copy) NSString *remark;
@end

初始化数据

我们controller这里只做数据显示,不去处理初始化数据的内容,因为如果加上这段代码可能导致它会很乱。所以我们将初始化放在了viewModel层处理。

+(Model*)getInitModel{
Model*model = [[Model alloc] init];
model.token=@"token";
model.type=@"type";
model.date=@“date";
model.time=@“time";
model.data=5.0;
return model;
}

在这里就可以将想要初始化的数据写上去了。那么在实例化这个controller的时候就需要传入两个参数了。

ViewStatus  //表示页面当前的状态
model       //带有页面展示的数据

controller的初始化

虽然我们提供了初始化方法,但万一有同学不知道,采用其它初始化方法如init呢?那么我们可以在viewDidLoad方法中,在[super viewDidLoad];之后写上

//如果没有正确调用init方法的处理
_newModel = _newModel ? : [ViewModel getInitModel];
  if(_viewStatus ==0){
    if([NSString isBlankString:_newModel.id]){
      _viewStatus = ViewStatusNew;
    }else{
    _viewStatus = ViewStatusRetrieve;
  }
}

这样一来,即使外面没有调用正确的初始化方法,我表单页面一样可以正常使用

录入项配置

一般表单应该都是用tableView来做的,所以这里只讨论tableView的情况。对于表单来说录入项一般都是固定那几个,所以可以将录入项配置起来,如:

+ (NSArray*) viewConfig{
NSArray*viewConfig=@[
@{
@"key":@“type",
@"title":@"类型"
},
@{
@"key":@“date",
@"title":@"日期"
},
@{
@"key":@“time",
@"title":@"时间"
},
@{
@"key":@"data",
@"title":@"数值"
},
@{
@"key":@“remark",
@"title":@"备注"
}
];
returnviewConfig;
}

这里最好是把key都配置成跟Model属性一样的值,方便在cellForRowAtIndexPath填充cell的时候可以直接使用KVC来取值。这么做一个不好的地方就是一旦Model里面的属性名改变了,而viewConfig没有及时改过来的话,是取不到值的。不过我觉得一来属性名一旦确认后较少去改;二来如果直接用属性访问的话,一旦属性过多,那赋值的代码量就偏大。以防万一我们可以在Model里面特意写上一个提示“如果修改属性名需要修改viewConfig的对应字段”,如

/**
*如果修改属性名需要修改viewModel中viewConfig的对应字段
*/
@interface Model :NSObject
@property(nonatomic, copy) NSString *token;
@property(nonatomic, copy) NSString *id;
@property(nonatomic, copy) NSString *type;
@property(nonatomic, copy) NSString *date;
@property(nonatomic, copy) NSString *time;
@property(assign, nonatomic)float data;
@property(nonatomic, copy) NSString *remark;
@end

所以在cellForRowAtIndexPath中就可以这么写(因为我这边的例子都不是直接在table上面录入的,而是用其它弹出层带有的框录入)

cell.textLabel.text= [item objectForKey:@"title"];
cell.detailTextLabel.text= [_newModel valueForKey:[item objectForKey:@"key"]];

可编辑性

由于业务不同,表单里面的每一项都可能存在可编辑与否的问题,那么我们可以将这部分的逻辑直接写到一个方法里面,当遍历到这个项的时候去根据这个方法来判断是否可以编辑。这样做可以将这部分业务的代码给统一起来,一来好找,二来代码更加规范了。

#pragma mark -cell是否可以编辑
-(BOOL)isCellCanEdit:(NSDictionary*)dict{
if([dict[@"key"] isEqualToString:@"type"]){
return NO;
}
if([dict[@"key"] isEqualToString:@“date"]){
if(_viewStatus==ViewStatusNew){
return YES;
}else{
return NO;
}
}
if([dict[@"key"] isEqualToString:@“time"]){
if(_viewStatus==ViewStatusNew){
return YES;
}else{
return NO;
}
}
if([dict[@"key"] isEqualToString:@“data"]){
if(_viewStatus==ViewStatusNew){
return YES;
}else{
if([_newModel.monitorDate isEqualToString:[NSDate currentDateStringWithFormat:@"yyyy-MM-dd"]]){
return YES;
}
return NO;
}
}
return YES;
}

那么在cellForRowAtIndexPath中就可以这么写

NSDictionary*item =_viewConfig[indexPath.row];
//控制cell的可编辑状态
cell.userInteractionEnabled= [self isCellCanEdit:item];

提交

因为我们传进来的_newModel其实就是要提交的那个model,所以当用户在表单上操作后,对应元素的值就可以直接赋值给_newModel对应的属性。而且需要做是否可以提交的处理,因为如果达到要求的时候,一般应该应该是把保存按钮置为可点状态。所以我们可以把这个判断封装起来,每次值改变后就调用这个方法,可以确保提交按钮的状态改变。

#pragma mark -页面是否可以提交,会改变按钮是否可以点击
-(void)viewCanSave{
if(_viewStatus==ViewStatusEdit){
//修改
if([[_newModel mj_JSONString] isEqualToString:[_oldModel mj_JSONString]]){
//证明没改过
self.navigationItem.rightBarButtonItem.enabled=false;
}else{
self.navigationItem.rightBarButtonItem.enabled=true;
}
}else{
//新增
//此处略(写上判断是否为空即可,至于输入合法性,可以留到保存按钮触发后提交前处理)
}
}

修改

当表单进入修改状态时,一般都会有这样的需求:当且仅当表单的元素有修改过,才允许提交。而我们每次用户操作后都把值赋值给了_newModel了,那么要怎么来判断是否用户有修改过呢?我们可以再申明一个变量_oldModel,然后当初始化的时候将_newModel copy一份给_oldModel。当然,要copy的话,这个Model需要遵守NSCopying协议,并且实现copyWithZone:方法,具体大家再网上搜索了。建议这里最好做深拷贝。那么viewDidLoad方法可以变成这样:

[super viewDidLoad];
//如果没有正确调用init方法的处理
_newModel = _newModel ? : [ViewModel getInitModel];
if(_viewStatus ==0){
if([NSString isBlankString:_newModel.id]){
_viewStatus = ViewStatusNew;
}else{
_viewStatus = ViewStatusRetrieve;
}
}
//判断是编辑还是新增
if([NSString isBlankString:_newModel.id]){
_viewStatus = ViewStatusNew;
}
//只有在编辑(非新增情况)才需要
if(_viewStatus == ViewStatusEdit){
_oldModel = [_newModel copy];
}
//…..

合法性验证

建议把合法性验证放在请求保存接口之前,而不是放在输入改变的时候。那么我们可以封装一个方法,把所有的合法性验证全都放在这个方法里面,然后请求保存接口之前先调用。

#pragma mark -合法性验证
-(BOOL)isViewValid{
if(_newModel.data>10){
//这里可以用HUD给用户抛出提示
return NO;
}
//其它的合法验证
return YES;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容