- XLForm基礎
- 簡介
- 建立
- 基本類的說明
- 自定義行
- 一些常用功能
- 表單取值
- 點選事件的實現
- 校驗表單資料
- 行的附加配置
- 監聽行的value值的改變
XLForm基礎
簡介
XLForm 是最靈活且最強大的建立動態表單的iOS庫。專案連結 https://github.com/xmartlabs/XLForm
建立
- 整合XLForm到專案
- 建立繼承自
XLFormViewController
的控制器 - 在控制器中建立表單
-(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
型別的屬性action
,XLFormAction
的類裡包含一些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];
複製程式碼