欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS实现自定义表单实例代码

程序员文章站 2023-12-18 18:17:04
前言 最近在开发一个app,需要让用户填写数据,然后上传到服务端进行计算并返回结果在客户端中展示。其中需要填写的数据项多达十几项,大部分是必填。所有表单数据在一个页面中实...

前言

最近在开发一个app,需要让用户填写数据,然后上传到服务端进行计算并返回结果在客户端中展示。其中需要填写的数据项多达十几项,大部分是必填。所有表单数据在一个页面中实现,在app中这样的设计其实挺逆天的,但产品经理坚持要这么弄,也只能硬着头皮写。页面的表单数据样式五花八门,下图是其中几行截图

iOS实现自定义表单实例代码

第一、二行的 textfield 其实是一个选择框,只能从下拉选项中选择一个。第三个只允许输入数字。

页面由另一个同学实现,表单的数据基本都在 cellforrowatindexpath 实现,结果是这样的:

iOS实现自定义表单实例代码

看着这么多的if...else...一下子就凌乱了。让我怎么接手实现网络接口,上传表单数据,难道也写这么多的if...else...?这么实现之后要改其中某行数据的话,比如增加或删除一行表单,就得改n个地方。这样不仅浪费时间,而且容易出错,要么改错了要么没改全。这样的代码后期维护成本太高,只能重写了。那么问题来了,怎么改?从何开始?

xlform

xlform is the most flexible and powerful ios library to create dynamic table-view forms. fully compatible with swift & obj-c.

xlform 是最灵活且最强大的创建动态表单的ios库。更多的使用方法可以参考这篇文章:

以下是这个库一个简单的结构图:

iOS实现自定义表单实例代码

最主要的是红色方框的三个类:xlformrowdescriptor, xlformsectiondescriptor,xlformdescriptor。xlformdescriptor结构和uitablview一样,有section,有row,它就是为成为uitableview的数据源而设计的。xlformrowdescriptor定义了每行表单的数据内容,包括行样式,标题,行类型,选择项内容,标签,合法性验证等。xlformsectiondescriptor是由xlformrowdescriptor组合而成的,而xlformsectiondescriptor最终又组成了xlformdescriptor。

由于我们要实现的app表单行样式更复杂,有的一行要提交两项数据,所以需要对xlformrowdescriptor做些改动。代码如下:

@property (strong, nonatomic) nsmutabledictionary *cellconfig;
@property (strong, nonatomic) nsdictionary *textfieldconfig;
@property (strong, readonly, nonatomic) nsstring *rowtype;
@property (strong, readonly, nonatomic) nsarray *leftoptions;
@property (strong, readonly, nonatomic) wweformrightselectoroption *rightoptions;
@property (strong, nonatomic) nsstring *title;
@property (strong, nonatomic) id value;
@property (strong, nonatomic) nsstring *tag;
@property (nonatomic) bool required;
@property (strong, nonatomic) wwebasetableviewcell *tableviewcell;
-(id)initwithrowtype:(nsstring *)rowtype
  title:(nsstring *)title
  leftoptions:(nsarray *)leftoptions
 rightoptions:(wweformrightselectoroption *)rightoptions;
-(wweformvalidation *)dovalidation;
@end
@interface wweformrightselectoroption : nsobject
@property (readonly, nonatomic) nsarray *rightoptions;
@property (readonly, nonatomic) nsstring *httpparameterkey;
@property (readonly, nonatomic) nsstring *selectortitle;
@property (nonatomic) nsinteger selectedindex;
+(wweformrightselectoroption *)formrightselectoroptionwithtitle:(nsstring *)title      httpparameterkey:(nsstring *)httpparameterkey      rightoptions:(nsarray *)rightoptions;

这样,表单数据就独立于ui,tableviewcell是可配置的。通过xlformrowdescriptor 来配置tableviewcell。只要指定行类型,就给出相应的类型的cell。tableviewcontroller中的cell是由xlformrowdescriptor提供的。

- (wwebasetableviewcell *)tableviewcell {
 if (!_tableviewcell) {
 id cellclass = [self cellclassesforrowdescriptortypes][self.rowtype];
 nsassert(cellclass, @"not defined xlformrowdescriptortype: %@", self.rowtype ?: @"");
 
 _tableviewcell = [[cellclass alloc] initwithstyle:uitableviewcellstyledefault reuseidentifier:nil];
 
 nsassert([_tableviewcell iskindofclass:[wwebasetableviewcell class]], @"uitableviewcell must extend from wwebasetableviewcell");
 _tableviewcell.rowdescriptor = self;
 }
 return _tableviewcell;
}

那么 xlformrowdescriptor 怎么根据不同的行给出不同的cell?cell需要继承同一个父类,这个父类足够简单,只有一个wweformrowdescriptor属性,其它需要实现的方法则由wwecellprotocal负责。

@class wweformrowdescriptor;
@interface wwebasetableviewcell : uitableviewcell<wwecellprotocal>
@property (nonatomic, weak) wweformrowdescriptor *rowdescriptor;
@end
@class wweformrowdescriptor;
@protocol wwecellprotocal <nsobject>
@required
@property (nonatomic, weak) wweformrowdescriptor *rowdescriptor;
-(void)configure;
-(void)update;
@end

另外,将表单配置数据独立出来,而不是写死在代码中。使用plist文件,这样初始化form时只需读取这个文件,就完成了cell的配置。后续如果要改动表单的内容,不改动样式,就只需修改plist文件,而无需改动代码。

iOS实现自定义表单实例代码

最后tableviewcontroller的代码就格外简单了:

iOS实现自定义表单实例代码

这样上传表单数据就无比轻松了, [self.form localvalidationerrors] 验证数据合法性,全部合法的话再调用 [self.form httpparameters] 就获取了所有的表单数据,传给网络接口就大功告成了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

上一篇:

下一篇: