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

前言

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

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

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

看着这么多的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库。更多的使用方法可以参考这篇文章://www.jb51.net/article/138943.htm

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

最主要的是红色方框的三个类: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文件,而无需改动代码。

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

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

总结

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

(0)

相关推荐

  • iOS中的表单按钮选项UIActionSheet常用方法整理

    什么是操作表单?看图: 一看图就明白了,毋需多说. 复制代码 代码如下: UIActionSheet* mySheet = [[UIActionSheet alloc]                             initWithTitle:@"ActionChoose"                              delegate:self                              cancelButtonTitle:@"Cance

  • iOS开发教程之XLForm的基本使用方法

    前言 在iOS开发中,开发"表单"界面,字段稍微多一点的一般都用UITableView来做,而XLForm就是这样一个框架,它是创建动态表格视图最牛逼的iOS库, 用它实现表单功能,非常简单,省心省力.但是很可惜,搜索了很多文章都只是翻译官方文档,很多人在使用该库的时候可能都被官方文档带走远了,不知道如何具体使用.正好最近也要用到这个库,所以写个入门使用文章供大家参考. 以下是这个库一个简单的结构图: 一. 导入项目 使用CocoaPods或者手动导入库文件,本人选择直接导入项目源文件

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

    前言 最近在开发一个APP,需要让用户填写数据,然后上传到服务端进行计算并返回结果在客户端中展示.其中需要填写的数据项多达十几项,大部分是必填.所有表单数据在一个页面中实现,在APP中这样的设计其实挺逆天的,但产品经理坚持要这么弄,也只能硬着头皮写.页面的表单数据样式五花八门,下图是其中几行截图 第一.二行的 textfield 其实是一个选择框,只能从下拉选项中选择一个.第三个只允许输入数字. 页面由另一个同学实现,表单的数据基本都在 cellForRowAtIndexPath 实现,结果是这

  • Vue表单实例代码

    什么是 Vue.js? Vue.js 是用于构建交互式的 Web 界面的库. Vue.js 提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单.灵活的 API. Vue.js 特点 简洁: HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单. 数据驱动: 自动追踪依赖的模板表达式和计算属性. 组件化: 用解耦.可复用的组件来构造界面. 轻量: ~24kb min+gzip,无依赖. 快速: 精确有效的异步批量 DOM 更新. 模块友好: 通过 NPM 或 Bower

  • Vue模仿ElementUI的form表单实例代码

    实现要求 模仿 ElementUI 的表单,分为四层结构:index 组件.Form 表单组件.FormItem 表单项组件.Input 和 CheckBox 组件,具体分工如下: index 组件: 实现:分别引入 Form 组件.FormItem 组件.Input 组件,实现组装: Form 表单组件: 实现:预留插槽.管理数据模型 model.自定义校验规则 rules.全局校验方法 validate: FormItem 表单项组件: 实现:预留插槽.显示 label 标签.执行数据校验.

  • JSP实现用于自动生成表单标签html代码的自定义表单标签

    本文实例讲述了JSP实现用于自动生成表单标签html代码的自定义表单标签.分享给大家供大家参考.具体如下: 这个是自己写的一个简单的JSP表单标签,用于自动生成checkbox,select,radio等标签,传入菜单集合生成html代码,自动选中指定值,用于java web项目的jsp页面. 1. Servlet部分代码: Map<String, String> map = new HashMap<String, String>(); map.put("2",

  • Vue自定义表单内容检查rules实例

    先看个例子 组件 <el-form-item label="手机号:" prop="phone_number"> <el-input v-model="formPerson.phone_number"></el-input> </el-form-item> script中 export default { data() { var validateMobilePhone = (rule, value

  • vee-validate vue 2.0自定义表单验证的实例

    亲测可用 学习vee-validate,首先可以去阅读官方文档,更为详细可以阅读官网中的规则. 一.安装 您可以通过npm或通过CDN安装此插件. 1. NPM npm install vee-validate --save 2. CDN <script src="path/to/vue.js"></script> <script src="path/to/vee-validate.js"></script> <

  • AngularJS自定义表单验证功能实例详解

    本文实例讲述了AngularJS自定义表单验证功能.分享给大家供大家参考,具体如下: Angular实现了大部分常用的HTML5的表单控件的类型(text, number, url, email, date, radio, checkbox),也实现了很多指令做为验证(required, pattern, minlength, maxlength, min, max). 在自定义的指令中,我们可以添加我们的验证方法到ngModelController的$validators对象上.为了取得这个c

  • Angular 4.x 动态创建表单实例

    本文将介绍如何动态创建表单组件,我们最终实现的效果如下: 在阅读本文之前,请确保你已经掌握 Angular 响应式表单和动态创建组件的相关知识,如果对相关知识还不了解,推荐先阅读一下 Angular 4.x Reactive Forms和 Angular 4.x 动态创建组件 这两篇文章.对于已掌握的读者,我们直接进入主题. 创建动态表单 创建 DynamicFormModule 在当前目录先创建 dynamic-form 目录,然后在该目录下创建 dynamic-form.module.ts

  • 浅析Angular19 自定义表单控件

    1 需求 当开发者需要一个特定的表单控件时就需要自己开发一个和默认提供的表单控件用法相似的控件来作为表单控件:自定义的表单控件必须考虑模型和视图之间的数据怎么进行交互 2 官方文档 -> 点击前往 Angular为开发者提供了ControlValueAccessor接口来辅助开发者构建自定义的表单控件,开发者只需要在自定义表单控件类中实现ControlValueAccessor接口中的方法就可以实现模型和视图之间的数据交互 interface ControlValueAccessor { wri

  • Angular4表单验证代码详解

     背景: 最近在itoo页面调整的时候,发现页面表单或者是文本框没有做基本的判断操作,所以着手demo一篇,希望对大家有帮助!! -------------------------------------------------------------------------------- 1.创建表单组件: ng g c login1 2.1单规则验证: <label>用户名:</label> <input type="text" #userNameRe

随机推荐