XLForm基礎

zN發表於2018-05-07
  • 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…

相關文章