认识XLForm

一 认识

XLForm是创建动态表格视图最灵活的第三方库,提供了各种cell样式,比较简单实用;

二 基本使用

  1. 创建控制器继承自XLFormViewController

  2. 创建form表单,添加section(组),添加row(行)

     XLFormDescriptor *form = [XLFormDescriptor formDescriptor];
     XLFormSectionDescriptor *section;
     XLFormRowDescriptor *row;
    
     section = [XLFormSectionDescriptor formSection];
     [form addFormSection:section];
     
     row = [XLFormRowDescriptor formRowDescriptorWithTag:kBuildName rowType:XLFormRowDescriptorTypeText title:@"楼栋名称"];
     row.required = YES;
     [self customizeFormRowFont:row];
     [section addFormRow:row];
    
  3. 表单赋值,不然表单不显示

     self.form = form;
    

三 修改基本属性

  1. 修改文字颜色,字体大小

    以XLFormRowDescriptorTypeText类型的cell为例,默认创建出来是这样的,

     row = [XLFormRowDescriptor formRowDescriptorWithTag:kBuildName rowType:XLFormRowDescriptorTypeText title:@"楼栋名称"];
    
01.png

假如要修改文字大小和颜色的话,需要这样做:

02.png
  1. 文本对齐方式
    XLForm中Text类型中的TextField文字默认是左对齐的,要是想满足右对齐的话,需要这样设置:

     [row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
    
  2. 添加cell的accessoryView

    [row.cellConfig setObject:@(UITableViewCellAccessoryDisclosureIndicator) forKey:@"accessoryType"];
    

那么得到的效果如下:(右边就会有一个小箭头)


03.png
  1. 其它类型的cell
    1. 数字类型XLFormRowDescriptorTypeInteger,会调起数字键盘:


      04.png
    2. XLFormRowDescriptorTypeBooleanSwitch,


      05.png
    3. pickerView类型XLFormRowDescriptorTypeSelectorPickerView,

      row = [XLFormRowDescriptor formRowDescriptorWithTag:kBuildConstruction rowType:XLFormRowDescriptorTypeSelectorPickerView title:@"建筑结构"];
      row.required = YES;
      row.selectorOptions =@[[XLFormOptionsObject formOptionsObjectWithValue:@"建筑结构一" displayText: @"建筑结构一"],
                       [XLFormOptionsObject formOptionsObjectWithValue:@"建筑结构二" displayText: @"建筑结构二"]
                       ];
      row.value = [XLFormOptionsObject formOptionsObjectWithValue:@"建筑结构一" displayText:@"建筑结构一"];
      [row.cellConfig setObject:@(UITableViewCellAccessoryDisclosureIndicator) forKey:@"accessoryType"];
      
06.png
  1. 日期类型XLFormRowDescriptorTypeDate,

     row = [XLFormRowDescriptor formRowDescriptorWithTag:kBuildTime rowType:XLFormRowDescriptorTypeDate title:@"建筑年份"];
    
row.value = [NSDate date];
[row.cellConfig setObject:@(UITableViewCellAccessoryDisclosureIndicator) forKey:@"accessoryType"];

四 自定义Cell

虽然XLForm中提供了很多种类型的cell,但是在实际开发中可能并不是非常满足自己的需求,这时候就需要我们去自定义cell了,例如:

07.png

XLForm中提供了选择器,但是一般情况下都是一个cell中只有一个cell,但是我们的需求是一个cell中展示两个选择器来选择,所以我就整理下,自定义这个cell的整体思路:

  1. 首先我创建了一个cell叫做XLFormTwoSelectorCell继承自XLFormBaseCell,然后发现,必须实现3个方法:
  • load()注册自定义的cell;

    +(void)load{}
    
  • configure()配置一些基本cell信息

    -(void)configure{}
    
  • update() 更新tableView中显示的值

    -(void)update{}
    

2.然后我查看了一个cell中只有一个selector的XLFormSelectorCell,是XLForm中的源代码,发现不管是一个selector还是两个selector都只是在点击cell某个位置弹出pickerView而已,所以首先我重写了成为响应者的方法:
我给cell左半部分和有半部分分别加了手势,点击时候成为第一响应者,弹出pickerView,

09.png
08.png

(然后会发现,因为是一个pickerView,所以点右边或者是点击左边每次pickerView并不能对应到当前的row,所以我就子安点击的时候让pickerView滑动到对应的row)

  1. 改变cell中左边Label和右边Label的值
10.png

4.整体代码:

#import "XLFormTwoSelectorCell.h"
NSString * const XLFormRowDescriptorCustomSelectorCell = @"XLFormRowDescriptorCustomSelectorCell";

@interface XLFormTwoSelectorCell() <UIPickerViewDelegate, UIPickerViewDataSource>

@property (weak, nonatomic) IBOutlet UILabel *leftTitleLabel;
@property (weak, nonatomic) IBOutlet UILabel *rightTitleLabel;

@property (strong, nonatomic) UIPickerView * pickerView;

@property (weak, nonatomic) IBOutlet UIView *leftView;
@property (weak, nonatomic) IBOutlet UIView *rightView;

@property(assign, nonatomic) NSInteger leftIndex;
@property(assign, nonatomic) NSInteger rightIndex;

//记录点击左边view还是右边view
@property(assign, nonatomic) BOOL isClickRight;

@property(strong, nonatomic) NSMutableDictionary *value;

@end

@implementation XLFormTwoSelectorCell

-(NSMutableDictionary *)value {
if (!_value) {
    _value = [NSMutableDictionary dictionary];
}
return _value;
}

-(UIPickerView *)pickerView
{
if (!_pickerView) {
    _pickerView = [[UIPickerView alloc] init];
    _pickerView.delegate = self;
    _pickerView.dataSource = self;
    [_pickerView selectRow:[self selectedIndex] inComponent:0 animated:NO];
}
return _pickerView;
}

-(UIView *)inputView {

if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorCustomSelectorCell]){
    return self.pickerView;
}
return [super inputView];
}

-(void)awakeFromNib {
[super awakeFromNib];

UITapGestureRecognizer *tapLeft = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapLeft)];
[self.leftView addGestureRecognizer:tapLeft];

UITapGestureRecognizer *tapRight = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRight)];
[self.rightView addGestureRecognizer:tapRight];
}

-(void)tapLeft {

self.isClickRight = NO;
[self.pickerView selectRow:self.leftIndex inComponent:0 animated:NO];
[self becomeFirstResponder];
}

-(void)tapRight {

self.isClickRight = YES;
[self.pickerView selectRow:self.rightIndex inComponent:0 animated:NO];
[self becomeFirstResponder];
}

-(BOOL)formDescriptorCellCanBecomeFirstResponder
{
  return (!self.rowDescriptor.isDisabled && ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorCustomSelectorCell]));
}

//点击cell的时候不让弹出pickerView
-(BOOL)formDescriptorCellBecomeFirstResponder
{
    return NO;
}

-(void)formDescriptorCellDidSelectedWithFormController:  (XLFormViewController *)controller
{

if (self.rowDescriptor.action.formBlock){
    self.rowDescriptor.action.formBlock(self.rowDescriptor);
}

 if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorCustomSelectorCell]){
        [controller.tableView selectRowAtIndexPath:nil animated:YES scrollPosition:UITableViewScrollPositionNone];
    }
}

- (BOOL)canBecomeFirstResponder
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorCustomSelectorCell]){
    return YES;
}
return [super canBecomeFirstResponder];
}

+(void)load {
[XLFormViewController.cellClassesForRowDescriptorTypes setObject:NSStringFromClass([XLFormTwoSelectorCell class]) forKey:XLFormRowDescriptorCustomSelectorCell];
}

-(void)configure
{
[super configure];
self.selectionStyle = UITableViewCellSelectionStyleNone;
}

//点击完成
-(void)update
{
[super update];
self.editingAccessoryType = self.accessoryType;

if (self.rowDescriptor.value) {
    NSDictionary *dict = self.rowDescriptor.value;
    self.leftTitleLabel.text = dict[@(0)];
    self.rightTitleLabel.text = dict[@(1)];
}
}

-(NSString *)valueDisplayText {
if (self.rowDescriptor.selectorOptions) {
    NSArray *array = self.rowDescriptor.selectorOptions[self.isClickRight][@"values"];
    NSInteger row = [self.pickerView selectedRowInComponent:0];
    return array[row];
}
return nil;
}

-(void)highlight
{
[super highlight];
if (self.isClickRight) {
    self.rightTitleLabel.textColor = self.tintColor;
}else {
    self.leftTitleLabel.textColor = self.tintColor;
}
}

-(void)unhighlight {

[super unhighlight];
if (self.isClickRight) {
    self.rightTitleLabel.textColor = [UIColor colorWithHexString:@"#222222"];
}else {
    self.leftTitleLabel.textColor = [UIColor colorWithHexString:@"#222222"];
}
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (self.rowDescriptor.valueTransformer){
    NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
    NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
    NSString * tranformedValue = [valueTransformer transformedValue:[[self.rowDescriptor.selectorOptions objectAtIndex:row] valueData]];
    if (tranformedValue){
        return tranformedValue;
    }
}
NSArray *array = self.rowDescriptor.selectorOptions[self.isClickRight][@"values"];
return array[row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorCustomSelectorCell]){
    NSArray *array = self.rowDescriptor.selectorOptions[self.isClickRight][@"values"];
    if (self.isClickRight) {
        self.rightTitleLabel.text = array[row];
        self.rightIndex = row;
        
        self.value[@(1)] = array[row];
    }else {
        self.leftTitleLabel.text = array[row];
        self.leftIndex = row;
        self.value[@(0)] = array[row];

    }
    self.rowDescriptor.value = self.value;
    [self setNeedsLayout];
}
}

#pragma mark - UIPickerViewDataSource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSArray *array = self.rowDescriptor.selectorOptions[self.isClickRight][@"values"];
return array.count;
}


#pragma mark - Helpers

-(NSInteger)selectedIndex
{
if (self.rowDescriptor.selectorOptions) {
    NSArray *array = self.rowDescriptor.selectorOptions[self.isClickRight][@"values"];
    return array.count;
}
return -1;
}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • 废话不多说,直接上干货 ---------------------------------------------...
    小小赵纸农阅读 3,348评论 0 15
  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,480评论 1 14
  • 自己到现在毕业一年,总结了自己在前段时间开发当中遇到的的一些细节问题,水平有限,希望有可以帮助大家的 1,在OC中...
    baixuancheng阅读 649评论 0 1
  • 有时候,蓦然之间,就是想开始一段简简单单的旅行,不用多远,也不用多久,一个人,一只包,一条路,一段旅程,一种心情,...
    梦梦_ada6阅读 276评论 0 0
  • 目标好远 什么才是个头? 每个男人基本上都会有自己的梦想 大部分男生的梦想都会差不多 买车肯定是必须的 相对于我们...
    小渣渣阅读 294评论 0 1