LMForm - iOS表單配置框架

LMForm

背景

通常,將一個(gè)頁面需要編輯/錄入多項(xiàng)信息的頁面稱為表單。iOS 實(shí)現(xiàn)表單大多數(shù)基于TableView,麻煩的是需要在UITableViewDataSource或者UITableViewDelegate的代理方法中寫很多if-else,與cell耦合嚴(yán)重,不易獲取用戶已編輯的數(shù)據(jù)。如果表單頁面的配置數(shù)據(jù)從服務(wù)端返回,不易實(shí)現(xiàn)。

1. 介紹

LMForm 是基于MVVM輕量級(jí)表單配置框架,把數(shù)據(jù)和事件整合為一個(gè)model,實(shí)現(xiàn)cell與model的綁定,只需操作model便可配置表單。項(xiàng)目地址:https://github.com/MaricleZhang/LMForm.git

2. 結(jié)構(gòu)

image
  • LMFormTypeManager : 負(fù)責(zé)管理類型與cellClass
  • LMFormModel:cell 的配置信息,事件回調(diào),數(shù)據(jù)校驗(yàn)回調(diào)
  • Cell:遵循LMFormCellProtocol協(xié)議,實(shí)現(xiàn)不同的cell
  • LMFormTableView :注冊(cè)cell類型,通過model,渲染表單
  • LMFormValidator:負(fù)責(zé)對(duì)數(shù)據(jù)的校驗(yàn)

3. 功能

  1. 支持動(dòng)態(tài)配置model來實(shí)現(xiàn)表單。
  2. 支持配置文本、輸入框、選擇器、日期選擇、地址選擇等。
  3. 支持快速提取數(shù)據(jù)。
  4. 支持?jǐn)?shù)據(jù)校驗(yàn),可自定義校驗(yàn)格式。
  5. 支持完全自定義cell類型。

4. 預(yù)覽

form.gif

5. 安裝

CocoaPods

在 Podfile 中進(jìn)行如下導(dǎo)入:

pod 'LMForm'

安裝

pod install

6. 使用

在項(xiàng)目中導(dǎo)入#import "LMForm.h"

1. 配置數(shù)據(jù)源

目前項(xiàng)目中集成以下類型:

類型 宏定義 Cell Class
文本 kFormTypeText LMFormCell
輸入框 kFormTypeInput LMFormInputCell
選擇器 kFormTypeSelector LMFormSelectorCell
日期選擇器 kFormTypeDate LMDateCell
地址輸入框 kFormTypeAddressInput LMFormAddressInputCell

可根據(jù)需求來選擇對(duì)應(yīng)的類型,例如輸入框的model配置代碼如下:

  // 輸入框
- (LMFormModel *)loadInput
{
    LMFormModel *model = [LMFormModel new];
    model.formType = kFormTypeInput;
    model.title = @"手機(jī)號(hào)";
    model.key = @"mobile";
    model.value = @"";
    model.placeholder = @"請(qǐng)輸入手機(jī)號(hào)";
    model.height = LM_XX_6(50);
    model.message = @"請(qǐng)輸入正確的手機(jī)號(hào)";
    model.limitLength = 11;
    model.validateBlock = ^BOOL(LMFormModel * _Nullable model) {
        if (![LMFormValidator isMobile:model.value])
        {
            [LMWindowHud showHud:model.message];
            return NO;
        }
        return YES;
    };
    return model;
}

可根據(jù)需要設(shè)置UI,輸入限制長(zhǎng)度,自定義校驗(yàn)等。

2. 創(chuàng)建tableview

創(chuàng)建基于LMFormTableView 的tableview,并且賦值渲染數(shù)據(jù),表單的創(chuàng)建完成。

    self.tableView.dataArray = self.dataArray;

3. 校驗(yàn)數(shù)據(jù)

提交時(shí),對(duì)數(shù)據(jù)源進(jìn)行自定義校驗(yàn),校驗(yàn)的邏輯是對(duì)model.validateBlock遍歷回調(diào)。

/**
 對(duì)數(shù)據(jù)源校驗(yàn)

 @param dataArray 數(shù)據(jù)源
 @return 全部校驗(yàn)通過返回YES,否則返回NO。
 */
+ (BOOL)validateDataArray:(NSArray<LMFormModel *> *)dataArray
{
    for (LMFormModel * _Nonnull obj in dataArray)
    {
        if (obj.validateBlock)
        {
            if (!obj.validateBlock(obj)) return NO;
        }
    }
    return YES;
}

4. 獲取數(shù)據(jù)源

因?yàn)長(zhǎng)MFormTableView中的cell與model綁定,只需遍歷獲取value即可。

7. Cell 類型的介紹

1. LMFormCell

基類cell:其他類型cell繼承該cell,主要功能顯示文本,不可編輯??筛鶕?jù)需求配置相應(yīng)UI和數(shù)據(jù)。

- (void)configModel:(LMFormModel *)model
{
    self.model = model;
    
    // data
    self.titleLabel.text = model.title;
    self.textField.placeholder = model.placeholder;
    self.textField.text = model.value;
    if (model.limitLength)
    {
        self.textField.limitLength = @(model.limitLength);
    }
    
    // UI
    self.line.hidden = model.hiddenLine;
    self.line.backgroundColor = LM_ObjDefault(model.separatorLineColor, LM_UIColorFromHEX(0xF4F4F4));
    self.titleLabel.textColor = LM_ObjDefault(model.leftTextColor, LM_UIColorFromHEX(0x666666));
    self.textField.textColor = LM_ObjDefault(model.rightTextColor, LM_UIColorFromHEX(0x333333));
    self.titleLabel.font = LM_ObjDefault(model.leftLabelFont, [UIFont systemFontOfSize:LM_XX_6(14)]);
    self.titleLabel.font = LM_ObjDefault(model.rightLabelFont, [UIFont systemFontOfSize:LM_XX_6(14)]);
}

2. LMFormInputCell

輸入Cell:可以編輯,可以對(duì)輸入長(zhǎng)度限制,輸入的text更新為model的value。

- (void)textDidChanged:(UITextField *)textField
{
    self.model.value = textField.text;
    if (self.model.valueDidChangedBlock)
    {
        self.model.valueDidChangedBlock(textField.text);
    }
}

3. LMFormSelectorCell

選擇器Cell:可以選擇對(duì)應(yīng)的item,需要配置數(shù)據(jù)NSArray<NSString *> *selectList,點(diǎn)擊cell底部彈窗pickerView

- (void)tapSelectedAction
{
    LMDefaultPickerView *pickView = [[LMDefaultPickerView alloc] initWithDataArray:self.model.selectList];
    @weakify(self)
    [LMPopupView showPopupViewWithPickView:pickView title:self.model.placeholder confirmBlock:^{
        @strongify(self)
        NSString *text = self.model.selectList[pickView.selectIndex];
        self.model.value = text;
        self.textField.text = text;
        if (self.model.valueDidChangedBlock)
        {
            self.model.valueDidChangedBlock(text);
        }
    } cancelBlock:^{
        
    }];
}

4. LMDateCell

選擇日期Cell:與選擇cell類似,底部彈窗datePickerView。目前只支持年月日。

- (void)tapSelectedAction
{
    @weakify(self)
    [LMPopupView showPopupViewWithPickView:self.datePicker title:self.model.placeholder confirmBlock:^{
        @strongify(self)
        NSDate *date = self.datePicker.date;
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:self.model.dateFormat ?: @"yyyy-MM-dd"];
        NSString *text = [formatter stringFromDate:date];
        self.model.value = text;
        self.textField.text = text;
    } cancelBlock:^{
        
    }];
}

5. LMFormAddressInputCell

地址輸入cell:主要用來輸入較多數(shù)字的信息,分兩行顯示。

6.自定義cell

創(chuàng)建

LMForm 支持cell的完全自定義,創(chuàng)建的自定義cell需要遵循協(xié)議LMFormCellProtocol,
協(xié)議的方法必須實(shí)現(xiàn),在自定義的cell中實(shí)現(xiàn)配置數(shù)據(jù)。如果LMFormModel中的屬性不能滿足需求,可以創(chuàng)建LMFormModel分類添加或者繼承。個(gè)人比較推薦分類的做法。

/** 根據(jù)model 配置對(duì)應(yīng)的cell  */
- (void)configModel:(LMFormModel *)model;

注冊(cè)

LMForm 維護(hù)一張注冊(cè)表建立key與cellClass的一一對(duì)應(yīng)關(guān)系,單例LMFormTypeManager中的keyCellTypes就是這個(gè)注冊(cè)表。注冊(cè)方法為

/**
 自定義cell時(shí)注冊(cè)方法,同一種cell只需要注冊(cè)一次。cls 需繼承UITableViewCell

 @param cls cell class
 @param key key
 */
- (void)registerCellClass:(Class)cls forKey:(NSString *)key;

需要注意的是注冊(cè)表是個(gè)字典,key的定義不能重復(fù)

8. 項(xiàng)目地址:Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容