ios html 表单,iOS实现自定义表单

本文介绍了如何利用XLForm库优化iOS应用中的复杂表单设计,通过调整XLFormRowDescriptor以支持多样化的表单需求,将数据配置分离到plist,简化TableViewController,并阐述了如何利用该库轻松处理网络接口和数据验证。重构后的代码更易于维护,降低后期修改成本。
摘要由CSDN通过智能技术生成

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

47e96d025742

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

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

47e96d025742

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

XLForm is the most flexible and powerful iOS library to create dynamic table-view forms. Fully compatible with Swift & Obj-C.

XLForm 是最灵活且最强大的创建动态表单的iOS库。以下是这个库一个简单的结构图:

47e96d025742

最主要的是红色方框的三个类: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

@property (nonatomic, weak) WWEFormRowDescriptor *rowDescriptor;

@end

@class WWEFormRowDescriptor;

@protocol WWECellProtocal

@required

@property (nonatomic, weak) WWEFormRowDescriptor *rowDescriptor;

-(void)configure;

-(void)update;

@end

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

47e96d025742

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

47e96d025742

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值