当前位置: 首页 > 工具软件 > XLForm > 使用案例 >

XLForm基础

甄成弘
2023-12-01
  • XLForm基础
    • 简介
    • 创建
    • 基本类的说明
    • 自定义行
  • 一些常用功能
    • 表单取值
    • 点击事件的实现
    • 校验表单数据
    • 行的附加配置
    • 监听行的value值的改变

XLForm基础

简介

XLForm 是最灵活且最强大的创建动态表单的iOS库。项目链接 https://github.com/xmartlabs/XLForm

创建

  1. 集成XLForm到项目
  2. 创建继承自XLFormViewController的控制器
  3. 在控制器中创建表单
    -(void)initializeForm{
    
        XLFormDescriptor * form;
        XLFormSectionDescriptor * section;
        XLFormRowDescriptor * row;
    
        form = [XLFormDescriptor formDescriptor];
        
        section = [XLFormSectionDescriptor formSectionWithTitle:@"section 1"];
        [form addFormSection:section];
    
        row = [XLFormRowDescriptor formRowDescriptorWithTag:@"realExamples" rowType:ZNFormRowDescriptorTypeInfo title:@"工单编码:"];
        [section addFormRow:row];
    
        self.form = form;
    
    }
    复制代码
    self.form = form; //把创建的表单赋值给当前控制器的表单,不然不显示

基本类的说明

创建一个表单,主要用到了三个类:

  • XLFormRowDescriptor
  • XLFormSectionDescriptor
  • XLFormDescriptor

一种表单定义是一个XLFormDescriptor实例包含一个或多个部分(XLFormSectionDescriptor实例),每部分包含几行(XLFormRowDescriptor实例)。你可能已经注意到DSL结构模拟的一个表格的结构(Table -->> Sections -- >> Rows)。由此产生的表格视图的结构(sections and rows order))反映了定义的结构

自定义行

创建一个自定义cell需要继承自XLFormBaseCell,需要遵循XLFormDescriptorCell协议

@protocol XLFormDescriptorCell <NSObject>

@required

@property (nonatomic, weak) XLFormRowDescriptor * rowDescriptor;

// initialise all objects such as Arrays, UIControls etc...
-(void)configure;
// update cell when it about to be presented
-(void)update;

@optional

// height of the cell
+(CGFloat)formDescriptorCellHeightForRowDescriptor:(XLFormRowDescriptor *)rowDescriptor;
// called to check if cell can became first responder
-(BOOL)formDescriptorCellCanBecomeFirstResponder;
// called to ask cell to assign first responder to relevant UIView.
-(BOOL)formDescriptorCellBecomeFirstResponder;
// called when cell is selected
-(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller;
// http parameter name used for network request
-(NSString *)formDescriptorHttpParameterName;

// is invoked when cell becomes firstResponder, could be used for change how the cell looks like when it's the forst responder.
-(void)highlight;
// is invoked when cell resign firstResponder
-(void)unhighlight;


@end
复制代码

其中有两个必须要实现的方法:

  • -(void)configure; //初始化配置
  • -(void)update; //更新数据

一旦一个自定义cell已经建立,cellClassesForRowDescriptorTypes 添加这个cell的定义。 一般注册cell在自定义cell的+(void)load方法中进行,即

+(void)load{
   [[XLFormViewController cellClassesForRowDescriptorTypes] setObject:[MYCustomCellClass class] forKey:kMyAppCustomCellType]; 
}
复制代码

创建一个自定义cell最少实现三个方法:

-(void)configure;

-(void)update;

+(void)load //不是必须,但推荐在这里进行注册操作

一些常用功能

表单取值

  • 可以通过-(NSDictionary *)formValues方法来获取表单的所有值,通过这个方法得到的是一个字典,字典中的key value 对应XLFormRowDescriptor的tag 和 value,
    • 但是要注意只有对XLFormRowDescriptor设置了tag值才可以通过该方法取到
    • 如果两个XLFormRowDescriptor的tag值相同,则通过-(NSDictionary *)formValues取到的字典中,只存在后加入的XLFormRowDescriptor的值
  • 可以通过tag获取XLFormRowDescriptor,再进行取值
    XLFormRowDescriptor *textViewRowDescriptor = [self.form formRowWithTag:@"place"];
    NSString *place = textViewRowDescriptor.value;
    复制代码

点击事件的实现

通过实现代理方法- (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller来实现cell的点击事件,当点击cell的时候会触发该方法。

如果想在控制器中实现点击事件可以使用Action对象

XLFormSectionDescriptor本身有一个XLFormAction类型的属性actionXLFormAction的类里包含一些block,方便我们在控制器中处理cell的点击事件。

首先在自定义的cell中

- (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller{
    if (self.rowDescriptor.action.formSelector){
        [controller performFormSelector:self.rowDescriptor.action.formSelector withObject:self.rowDescriptor];
    }
    ...
}
复制代码

在控制器中

 row = [XLFormRowDescriptor formRowDescriptorWithTag:@"submit" rowType:ZNFormRowDescriptorTypeSubmitBtn title:@""];
 row.value = @"提交";
 row.action.formSelector = @selector(submitClick);
 [section addFormRow:row];
 
 ...
 - (void)submitClick{
     
 }
复制代码

校验表单数据

校验器

row = [XLFormRowDescriptor formRowDescriptorWithTag:@"int" rowType:XLFormRowDescriptorTypeInteger title:@"Integer"];
[row.cellConfigAtConfigure setObject:@"Required..." forKey:@"textField.placeholder"];
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
row.required = YES;
[row addValidator:[XLFormRegexValidator formRegexValidatorWithMsg:@"greater than 50 and less than 100" regex:@"^([5-9][0-9]|100)$"]];
[section addFormRow:row];
复制代码

得到所有行验证错误我们可以调用xlformviewcontroller方法: -(NSArray *)formValidationErrors;

也可以自定义一个校验器,实现常用的校验方法,方便调用,自定义的校验器必须要遵循XLFormValidatorProtocol协议

#import "XLFormValidatorProtocol.h"

@interface MyFormValidator : NSObject<XLFormValidatorProtocol>
+(MyFormValidator *)passwordValidator;
@end

#import "MyFormValidator.h"
#import "XLFormValidationStatus.h"
#import "XLFormRegexValidator.h"

@implementation MyFormValidator

//必须要实现的协议方法
-(XLFormValidationStatus *)isValid:(XLFormRowDescriptor *)row
{
    return [XLFormValidationStatus formValidationStatusWithMsg:nil status:YES rowDescriptor:row];
}


#pragma mark - Validators

+(XLFormValidator *)passwordValidator
{
    return [XLFormRegexValidator formRegexValidatorWithMsg:@"At least 6, max 32 characters" regex:@"^(?=.*\\d)(?=.*[A-Za-z]).{6,32}$"];
}


@end

复制代码

使用自定义的校验器

 row = [XLFormRowDescriptor formRowDescriptorWithTag:@"password" rowType:XLFormRowDescriptorTypePassword title:@"Password"];
 [row addValidator:[MyFormValidator passwordValidator]];
 [section addFormRow:row];
复制代码

行的附加配置

可以通过kvc的方式进行一些额外的属性配置你只需要去cellconfig或cellconfigatconfigure字典属性添加属性。cellconfig和cellconfigatconfigure之间的主要区别是时属性设置。cellconfig属性设置一个cell每次即将显示。cellconfigatconfigure,设置属性后的cell 执行init方法称为只有一次。

row = [XLFormRowDescriptor formRowDescriptorWithTag:@"place" rowType:ZNFormRowDescriptorTypeTextView title:@"故障位置:"];
[row.cellConfig setObject:@(10) forKey:@"textViewMaxNumberOfCharacters"];
[section addFormRow:row];
复制代码

监听行的value值的改变

  • 通过监听一行的数据值来决定另一行的状态,如显隐,禁用等

    hidden属性控制显示隐藏 disabled属性控制是否可以交互

    实现下面的方法

    注意要先实现super方法

-(void)formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)rowDescriptor oldValue:(id)oldValue newValue:(id)newValue{
    // super implmentation MUST be called
    
    [super formRowDescriptorValueHasChanged:rowDescriptor oldValue:oldValue newValue:newValue];
    
    if ([rowDescriptor.tag isEqualToString:@"OrdersPerson"]) {
       ...
    }
}
复制代码
  • 另一种动态显示的方式
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"switch" rowType:ZNFormRowDescriptorTypeSwitch title:@"是否显示section2"];
row.value = @1;
[section addFormRow:row];
    
section = [XLFormSectionDescriptor formSectionWithTitle:@"测试表单section2"];
section.hidden = [NSString stringWithFormat:@"$switch==0"];
[form addFormSection:section];
复制代码

demo地址 参考文献 www.jianshu.com/p/679e32976…

转载于:https://juejin.im/post/5aefff61f265da0b845558f1

 类似资料: