YIForm iOS平臺(tái)定制表單是偷,輕量級(jí),好用好用

iOS 上非常好用的表單工具募逞。兼容swiftOC
參考 XLForm RETableViewManager以及swift庫 Eureka
由于平臺(tái)審核原因,請(qǐng)giithub自己搜索YIForm

屏幕錄制2021-04-27 下午4.49.52.2021-04-27 17_09_21.gif

以下為內(nèi)部結(jié)構(gòu)圖:


1.png

YIFormManager

//
//  YIFormManager.h
//  YIForm
//
//  Created by Yilia on 2020/10/12.
//

#import <Foundation/Foundation.h>
#import "YIFormMacro.h"

NS_ASSUME_NONNULL_BEGIN

/// 創(chuàng)建 section
FOUNDATION_EXPORT YIFormSection *Section(void);
/// 創(chuàng)建 row
/// @param rowClass row class
FOUNDATION_EXPORT __kindof YIFormRow *Row(id rowClass);


typedef NS_ENUM(NSUInteger, XLPredicateType) {
    XLPredicateTypeDisabled = 0,
    XLPredicateTypeHidden
};

@interface YIFormManager : NSObject
// 默認(rèn) NO
@property (nonatomic) BOOL disabled;
/// 對(duì)應(yīng)tableView
@property (nullable, weak, nonatomic, readonly) UITableView *tableView;

/// sections
@property (strong, nonatomic, readonly) NSArray<__kindof YIFormSection *> *sections;
/// 初始化方法
/// @param tableView  tableView
+ (instancetype)managerForTableView:(UITableView *)tableView;

/// 初始化方法
/// @param tableView  tableView
- (instancetype)initWithTableView:(UITableView *)tableView;


// MARK: - 刷新

/// 重新加載 sections
/// @param sections section 數(shù)組
- (void)reloadSections:(NSArray<YIFormSection *> *)sections;
/// 重新加載
/// @param rows row 數(shù)組
- (void)reloadRows:(NSArray<YIFormRow *> *)rows;

/// 重新加載 sections
/// @param indexes indexes
- (void)reloadSectionsAt:(NSIndexSet *)indexes;

/// 重新加載
/// @param indexPaths indexPaths
- (void)reloadRowsAt:(NSArray<NSIndexPath *> *)indexPaths;

// MARK: - 檢索
/// <#Description#>
/// @param row <#row description#>
-(NSIndexPath *)indexPathForRow:(YIFormRow *)row;

-(NSUInteger)indexForSection:(YIFormSection *)section;
///
/// tag 對(duì)應(yīng) section
/// @param tag section tag
- (nullable YIFormSection *)sectionWithTag:(NSString *)tag;
/// tag 對(duì)應(yīng) row
/// @param tag row tag
- (nullable __kindof YIFormRow *)rowWithTag:(NSString *)tag;

/// indexPath 對(duì)應(yīng)的 row
/// @param indexPath indexPath
- (nullable __kindof YIFormRow *)rowAtIndexPath:(NSIndexPath *)indexPath;
// MARK: - 增 刪

/// 添加 sections
/// @param sections section 數(shù)組
- (void)addSections:(NSArray<YIFormSection *> *)sections;
/// 移除 sections
/// @param sections section 數(shù)組
- (void)removeSections:(NSArray<YIFormSection *> *)sections;
/// 移除indexes 對(duì)應(yīng)的 sections
/// @param indexes index 數(shù)組
- (void)removeSectionsAt:(NSIndexSet *)indexes;

/// 移除所有
- (void)removeAll;

/// 移除 row
/// @param formRow row
-(void)removeRow:(YIFormRow *)formRow;

/// 移除 tag 對(duì)應(yīng)的 row
/// @param tag row tag
-(void)removeRowWithTag:(nonnull NSString *)tag;

// MARK: -

/// @param formRow formRow
/// @param oldValue oldValue
/// @param newValue newValue
-(void)formRowValueHasChanged:(YIFormRow *)formRow oldValue:(id)oldValue newValue:(id)newValue;

/// 更新ui
/// @param rows
- (void)displayRows:(NSArray<YIFormRow *> *)rows;

@end

NS_ASSUME_NONNULL_END

YIFormSection

//
//  YIFormSection.h
//  YIForm
//
//  Created by Yilia on 2020/10/12.
//

#import <Foundation/Foundation.h>
#import "YIFormRow.h"

extern CGFloat const YIFormSectionHeaderHeightAutomatic;
extern CGFloat const YIFormSectionFooterHeightAutomatic;

@class YIFormManager;
NS_ASSUME_NONNULL_BEGIN

@interface YIFormSection : NSObject
/// 默認(rèn) NO
@property (nonatomic, assign) BOOL disabled;
///
@property (strong, nonatomic, nullable) NSString *tag;
/// 對(duì)應(yīng)的rows
@property (strong, nonatomic, readonly) NSArray<__kindof YIFormRow *> *rows;
/**
 A view object to display in the header of the specified section of the table view.
 */
@property (strong, readwrite, nonatomic) UIView *headerView;

/**
 A view object to display in the footer of the specified section of the table view.
 */
@property (strong, readwrite, nonatomic) UIView *footerView;

/**
 The height of the header of the specified section of the table view.
 */
@property (assign, readwrite, nonatomic) CGFloat headerHeight;

/**
 The height of the footer of the specified section of the table view.
 */
@property (assign, readwrite, nonatomic) CGFloat footerHeight;
/**
 Section index in UITableView.
 */
@property (assign, readonly, nonatomic) NSUInteger index;

/// section 圓 半徑
@property (nonatomic) CGFloat cornerRadius;

/// cell 內(nèi)容與邊緣間距
@property (nonatomic, assign) CGFloat horizontalInset;

/// 對(duì)應(yīng)的 formManager
@property (nonatomic, weak, null_unspecified) YIFormManager * formManager;

/// 添加 rows
/// @param rows 數(shù)組
- (void)addRows:(NSArray<YIFormRow *> *)rows;

/// 刪除rows
/// @param rows 數(shù)組
- (void)removeRows:(NSArray<YIFormRow *> *)rows;

/// 刪除對(duì)應(yīng)的indexes 的rows
/// @param indexes 數(shù)組
- (void)removeRowsAt:(NSIndexSet *)indexes;

/// 在 index 處插入 row
/// @param row row
/// @param index index
- (void)insertRow:(YIFormRow *)row at:(NSInteger)index;

/// tags 對(duì)應(yīng)的row
/// @param tags tags 數(shù)組
- (NSArray<__kindof YIFormRow *> *)rowsWithTags:(NSArray<NSString *> *)tags;

/// tag 對(duì)應(yīng)的row
/// @param tag tag
- (nullable __kindof YIFormRow *)rowWithTag:(NSString *)tag;

/// 刷新
- (void)reload;
+ (instancetype)section;
@end

NS_ASSUME_NONNULL_END

YIFormRow

//
//  YIFormRow.h
//  YIForm
//
//  Created by Yilia on 2020/10/12.
//

#import <Foundation/Foundation.h>
#import "YIFormCell.h"
@class YIFormAction;
@class YIFormSection;
NS_ASSUME_NONNULL_BEGIN

extern CGFloat YIFormRowInitialHeight;

typedef void(^YIOnChangeBlock)(id __nullable oldValue, id __nullable newValue, YIFormRow * row);

@interface YIFormRow : NSObject

//@property(nonatomic) BOOL hidden;
/// 是否 disabled 默認(rèn)NO
@property (nonatomic) BOOL disabled;
/// 是否 required 默認(rèn)NO
@property (nonatomic) BOOL required;

///
@property (nullable, strong, nonatomic) NSString *tag;

/// title
@property (nullable, nonatomic, copy) NSString *title;

/// 對(duì)應(yīng)的cell
@property (nonnull, strong, nonatomic, readonly) Class cellClass;
/// 當(dāng)前cellclass
@property (strong, nonatomic, readonly) Class currentCellClass;
/// 值
@property(nonatomic, strong, nullable) id value;

/// 行高 default is 44.0f
@property (nonatomic, assign) CGFloat height;
/// cell 內(nèi)縮進(jìn)
@property (nonatomic, assign) UIEdgeInsets contentEdgeInsets;
/// 分割線 左 縮進(jìn)
@property (nonatomic) CGFloat separatorLeftInset;
/// 分割線 右 縮進(jìn)
@property (nonatomic) CGFloat separatorRightInset;
/// 自動(dòng)刷新 默認(rèn) NO
@property (nonatomic) BOOL autoRefresh;
// XLForm

@property (nonatomic, assign  ) UITableViewCellStyle cellStyle;

@property (nonatomic, copy, nullable) YIOnChangeBlock onChangeBlock;

@property (nonatomic, strong) NSMutableDictionary * cellConfig;
//@property (nonatomic, strong) NSMutableDictionary * cellConfigForSelector;
@property (nonatomic, strong) NSMutableDictionary * cellConfigIfDisabled;
@property (nonatomic, strong) NSMutableDictionary * cellConfigAtConfigure;

// RETableViewManager
///
@property (strong, nonatomic) UIColor *containerBackgroundColor;
///
@property (nullable, strong, nonatomic) UIColor *separatorColor;
@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle;
@property (assign, readwrite, nonatomic) UITableViewCellSelectionStyle selectionStyle;
@property (assign, readwrite, nonatomic) UITableViewCellAccessoryType accessoryType;
@property (assign, readwrite, nonatomic) UITableViewCellEditingStyle editingStyle;
@property (strong, readwrite, nonatomic) UIView *accessoryView;

@property (copy, nonatomic) void (^selectionHandler)(__kindof YIFormRow *item);

@property (copy, nonatomic) void (^accessoryButtonTapHandler)(__kindof YIFormRow *item);
@property (copy, nonatomic) void (^insertionHandler)(__kindof YIFormRow *item);
// deletionHandler deletionHandlerWithCompletion 配置 二選一
@property (copy, nonatomic) void (^deletionHandler)(__kindof YIFormRow *item);
@property (copy, nonatomic) void (^deletionHandlerWithCompletion)(__kindof YIFormRow *item, void (^)(void));
@property (copy, readwrite, nonatomic) BOOL (^moveHandler)(YIFormRow *item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath);
@property (copy, readwrite, nonatomic) void (^moveCompletionHandler)(YIFormRow *item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath);
@property (copy, readwrite, nonatomic) void (^cutHandler)(__kindof YIFormRow *item);
@property (copy, readwrite, nonatomic) void (^copyHandler)(__kindof YIFormRow *item);
@property (copy, readwrite, nonatomic) void (^pasteHandler)(__kindof YIFormRow *item);

/// row 對(duì)應(yīng) indexPath
@property (strong, nonatomic, readonly) NSIndexPath *indexPath;
/// row 對(duì)應(yīng)的cell
@property (strong, nonatomic, readonly) __kindof YIFormCell *cell;
/// row 所在section
@property (nonatomic, weak, null_unspecified) YIFormSection *section;

- (void)reload;

/// special cell class init
/// @param cellClass subclass of YIFormCell
- (instancetype)initWithCellClass:(Class)cellClass;

+ (instancetype)row;

+ (instancetype)rowWithCellClass:(Class)cellClass;

+ (instancetype)rowWithContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets;

+ (instancetype)rowWithCellClass:(nullable Class)cellClass title:(nullable NSString *)title value:(NSString *)value contentEdgeInsets:(UIEdgeInsets)contentEdgeInsets;
@end

NS_ASSUME_NONNULL_END

YIFormCell

//
//  YIFormCell.h
//  YIForm
//
//  Created by Yilia on 2020/10/12.
//

#import <UIKit/UIKit.h>

@class YIFormRow;

NS_ASSUME_NONNULL_BEGIN
@protocol YIFormCellProtocol <NSObject>

@required



//-(BOOL)formDescriptorCellCanBecomeFirstResponder;
//-(BOOL)formDescriptorCellBecomeFirstResponder;
//-(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller;

//-(void)highlight;

//-(void)unhighlight;




@end

@interface YIFormCell : UITableViewCell<YIFormCellProtocol>
@property (strong, nonatomic, readonly) UIView *containerView;
///
//@property (nonnull, strong, nonatomic, readonly) UIView *customContentView;
///
@property (strong, nonatomic) UIColor *separatorColor;
@property (nonatomic, weak) __kindof YIFormRow * row;

/// top 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat topMargin;
/// left 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat leftMargin;

/// right 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat rightMargin;

/// bottom 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat bottomMargin;
/// 分割線 左 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat separatorLeftMargin;

/// 分割線 右 距 tableview 縮進(jìn)
@property (nonatomic, readonly) CGFloat separatorRightMargin;

/// 初始化配置 添加UI 布局等
-(void)configure;

/// 更新數(shù)據(jù) 或 UI布局
-(void)update;

@end

NS_ASSUME_NONNULL_END

demo

//
//  YIViewController.m
//  YIForm
//
//  Created by yiliazhang on 10/12/2020.
//  Copyright (c) 2020 yiliazhang. All rights reserved.
//

#import "YIViewController.h"
#import <YIForm/YIForm.h>
#import "YIAttachFormRow.h"
#import "YIFormRowText.h"
#import <Masonry/Masonry.h>
#import "GWAuthInfoCell.h"
#import "YIFormTextCell.h"
#import "YIMessageViewController.h"

@interface YIViewController ()<UIDocumentPickerDelegate, UIDocumentInteractionControllerDelegate>
///
@property (nonnull, strong, nonatomic) YIFormManager *formManager;
///
@property (nonnull, strong, nonatomic) UITableView *tableView;
/// tag
@property (nonatomic, copy) NSString *currrentFileUploadRowTag;


// Deletable items with confirmation

@property (strong, readwrite, nonatomic) YIFormRow *itemToDelete;
@property (copy, readwrite, nonatomic) void (^deleteConfirmationHandler)(void);

@end

@implementation YIViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"編輯" style:UIBarButtonItemStyleDone target:self action:@selector(switchTableEdit:)];
    
    self.tableView.frame = self.view.bounds;
    [self.view addSubview:self.tableView];
    // Do any additional setup after loading the view, typically from a nib.
    self.formManager = [YIFormManager managerForTableView:self.tableView];
    [self refreshAction:nil];
}

- (IBAction)refreshAction:(id)sender {
    [self.formManager removeAll];
    NSArray *sections = @[
        [self accessoryTypeSection],
        [self specialCellClassSection],
        [self customAccessorySection],
        [self randomSection],
        [self deletableSection],
        [self deleteConfirmSection],
        [self insertSection],
        [self movableSection],
        [self movableAndDeletableSection],
        [self copyCutPastSection],
    ];
    [self.formManager addSections:sections];
    [self.tableView reloadData];
}

- (IBAction)removeAction:(id)sender {
    
}
- (void)switchTableEdit:(UIBarButtonItem *)sender {
    self.editing = !self.editing;
    self.tableView.editing = self.editing;
    [sender setTitle:self.editing ? @"完成" : @"編輯"];
}

- (YIFormSection *)randomSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        //        __weak typeof(self) weakSelf = self;
        NSString *title = [NSString stringWithFormat:@"random %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
//        YIFormRow *row = [self telephoneRow];
        if (r == 1) {
            row.disabled = YES;
            row.separatorStyle = UITableViewCellSeparatorStyleNone;
            row.title = @"disabled - random";
        }
                row.contentEdgeInsets = UIEdgeInsetsMake(20, 40, 10, 30);
        row.separatorLeftInset = 20;
        row.separatorRightInset = 20;
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    section.headerHeight = 20;
    section.footerHeight = 20;
    [section addRows:rows];
    section.cornerRadius = 20;
    section.horizontalInset = 50;
    return section;
}


- (YIFormSection *)customAccessorySection {
    // 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        NSString *title = [NSString stringWithFormat:@"customAccessory %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        UIButton *button = [[UIButton alloc] init];
        button.frame = CGRectMake(0, 0, 50, 30);
        [button setTitle:@"點(diǎn)擊" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(accessoryButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        button.backgroundColor = [UIColor blackColor];
        row.accessoryView = button;
        
        [rows addObject:row];
        r++;
    }
    
    YIFormSection *section = Section();
    [section addRows:rows];
    section.headerView = [self headerViewWithTitle:@" custom Accessory \r\n 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset"];
    section.footerView = [self footerView];
    
    return section;
}

- (YIFormSection *)accessoryTypeSection {
    // 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        NSString *title = [NSString stringWithFormat:@"accessoryType %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        row.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        row.accessoryButtonTapHandler = ^(__kindof YIFormRow * _Nonnull item) {
            NSLog(@"accessoryButtonTapHandler");
        };
        [rows addObject:row];
        r++;
    }
    
    YIFormSection *section = Section();
    [section addRows:rows];
    section.headerView = [self headerViewWithTitle:@"accessoryType \r\n 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset"];
    section.footerHeight = 20;
    return section;
}

- (YIFormSection *)specialCellClassSection {
    // 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        NSString *title = [NSString stringWithFormat:@"accessoryType %d", r];
        YIFormRow *row = [self rowWithTitle:title specialCellClass:[YIFormTextCell class]];
        row.title = @"asfasf";
        row.value = @"dddd";
        row.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        row.accessoryButtonTapHandler = ^(__kindof YIFormRow * _Nonnull item) {
            NSLog(@"accessoryButtonTapHandler");
        };
        [rows addObject:row];
        r++;
    }
    
    YIFormSection *section = Section();
    [section addRows:rows];
    section.headerView = [self headerViewWithTitle:@"accessoryType \r\n 有accesoryView 的情況下就不要設(shè)置 contentEdgeMargins 或 horizontalInset"];
    section.footerHeight = 20;
    return section;
}

- (YIFormSection *)insertSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        //        __weak typeof(self) weakSelf = self;
        NSString *title = [NSString stringWithFormat:@"insert %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        
        if (r == 1) {
            row.disabled = YES;
            row.title = @"disabled - insert";
        }
        row.insertionHandler = ^(YIFormRow *item) {
            NSLog(@"Insertion handler callback");
        };
        row.editingStyle = UITableViewCellEditingStyleInsert;
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    section.headerView = [self headerViewWithTitle:@"insert 功能"];
    section.footerHeight = 20;
    [section addRows:rows];
    return section;
}

- (YIFormSection *)movableSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 3;
    while (r < maxRow) {
        //        __weak typeof(self) weakSelf = self;
        NSString *title = [NSString stringWithFormat:@"movable %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        row.moveHandler = ^BOOL(id item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath) {
            return YES;
        };
        row.moveCompletionHandler = ^(YIFormRow *item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath) {
            NSLog(@"Moved item: %@ from [%li,%li] to [%li,%li]", item.title, (long) sourceIndexPath.section, (long) sourceIndexPath.row, (long) destinationIndexPath.section, (long) destinationIndexPath.row);
        };
        if (r == 1) {
            row.disabled = YES;
            row.title = @"disabled - movable";
        }
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    section.headerView = [self headerViewWithTitle:@"move 功能"];
    section.footerHeight = 20;
    [section addRows:rows];
    return section;
}

- (YIFormSection *)deletableSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 7;
    while (r < maxRow) {
        //        __weak typeof(self) weakSelf = self;
        NSString *title = [NSString stringWithFormat:@"deletable %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        
        if (r == 1) {
            row.disabled = YES;
            row.title = @"disabled - deletable";
            row.separatorColor = [UIColor greenColor];
        } else if (r == 2) {
            
            row.separatorColor = [UIColor blackColor];
        } else if (r == 3) {
            row.separatorColor = [UIColor clearColor];
        } else if (r == 4) {
            row.separatorColor = [UIColor blueColor];
        } else {
            row.separatorStyle = UITableViewCellSeparatorStyleNone;
        }
        row.contentEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 20);
        row.separatorLeftInset = 5;
        row.separatorRightInset = 20;
        
        row.editingStyle = UITableViewCellEditingStyleDelete;
        row.deletionHandler = ^(YIFormRow *item) {
            NSLog(@"Item removed: %@", item.title);
        };
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    [section addRows:rows];
    section.cornerRadius = 10;
    section.horizontalInset = 20;
    return section;
}

- (YIFormSection *)deleteConfirmSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 1;
    while (r < maxRow) {
        __weak typeof(self) weakSelf = self;
        NSString *title = [NSString stringWithFormat:@"deleteConfirm %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        row.editingStyle = UITableViewCellEditingStyleDelete;
        row.deletionHandlerWithCompletion = ^(YIFormRow *item, void (^completion)(void)) {
            [weakSelf showAlert:item];
            weakSelf.itemToDelete = item;
            // Assign completion block to deleteConfirmationHandler for future use
            weakSelf.deleteConfirmationHandler = completion;
        };
        
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    section.headerView = [self headerViewWithTitle:@"delete 刪除功能"];
    section.footerHeight = 20;
    [section addRows:rows];
    return section;
}

- (YIFormSection *)movableAndDeletableSection {
    NSMutableArray *rows = [NSMutableArray array];
    int r = 0;
    int maxRow = 2;
    while (r < maxRow) {
        NSString *title = [NSString stringWithFormat:@"movableAndDeletable %d", r];
        YIFormRow *row = [self rowWithTitle:title tag:title];
        row.editingStyle = UITableViewCellEditingStyleDelete;
        
        row.moveHandler = ^BOOL(id item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath) {
            return YES;
        };
        row.moveCompletionHandler = ^(YIFormRow *item, NSIndexPath *sourceIndexPath, NSIndexPath *destinationIndexPath) {
            NSLog(@"Moved item: %@ from [%li,%li] to [%li,%li]", item.title, (long) sourceIndexPath.section, (long) sourceIndexPath.row, (long) destinationIndexPath.section, (long) destinationIndexPath.row);
        };
        [rows addObject:row];
        r++;
    }
    YIFormSection *section = Section();
    section.headerView = [self headerViewWithTitle:@"move delete 功能"];
    section.headerHeight = 20;
    section.footerHeight = 20;
    [section addRows:rows];
    return section;
}


- (YIFormSection *)copyCutPastSection {
    YIAttachFormRow *copyItem = [[YIAttachFormRow alloc] init];
    copyItem.title = @"copy";
    copyItem.selectionHandler = ^(__kindof YIFormRow * _Nonnull item) {
        //        [item deselectRowAnimated:YES];
    };
    copyItem.copyHandler = ^(YIFormRow *item) {
        [UIPasteboard generalPasteboard].string = @"Copied item #1";
    };
    
    
    YIAttachFormRow *pasteItem = [[YIAttachFormRow alloc] init];
    pasteItem.title = @"paste";
    pasteItem.selectionHandler = ^(__kindof YIFormRow * _Nonnull item) {
        //        [item deselectRowAnimated:YES];
    };
    pasteItem.pasteHandler = ^(YIFormRow *item) {
        item.title = [UIPasteboard generalPasteboard].string;
        [item reload];
    };
    
    YIAttachFormRow *cutCopyPasteItem = [[YIAttachFormRow alloc] init];
    cutCopyPasteItem.title = @"paste";
    cutCopyPasteItem.copyHandler = ^(YIFormRow *item) {
        [UIPasteboard generalPasteboard].string = @"Copied item #3";
    };
    cutCopyPasteItem.pasteHandler = ^(YIFormRow *item) {
        item.title = [UIPasteboard generalPasteboard].string;
        [item reload];
    };
    cutCopyPasteItem.cutHandler = ^(YIFormRow *item) {
        item.title = @"(Empty)";
        [UIPasteboard generalPasteboard].string = @"Copied item #3";
        //        [item reload];
    };
    
    YIFormSection *section = Section();
    section.headerView = [self headerViewWithTitle:@"copy cut paste 功能"];
    section.disabled = self.tableView.editing;
    section.headerHeight = 20;
    section.footerHeight = 20;
    [section addRows:@[copyItem, pasteItem, cutCopyPasteItem]];
    return section;
}

- (UIView *)headerViewWithTitle:(NSString *)title {
    UIView *headerView = [[UIView alloc] init];
    headerView.backgroundColor = [UIColor redColor];
    headerView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 100);
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(headerView.bounds, 20, 5)];
    [headerView addSubview:label];
    label.text = title;
    label.numberOfLines = 0;
    
    UIButton *button = [[UIButton alloc] init];
    [button setTitle:@"點(diǎn)" forState:UIControlStateNormal];
    
    
    return headerView;
}

- (UIView *)footerView {
    UIView *footerView = [[UIView alloc] init];
    footerView.backgroundColor = [UIColor orangeColor];
    footerView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 5);
    return footerView;
}
- (__kindof YIFormRow *)telephoneRow {
    GWAuthInfoRow *row2 = [[GWAuthInfoRow alloc] init];
    row2.selectionStyle = UITableViewCellSelectionStyleNone;
    row2.message = @"您提交的認(rèn)證信息未通過審核馋评,請(qǐng)修訂放接、完善";
    row2.tip = @"對(duì)結(jié)果有疑問請(qǐng)致電:020-12231232";
    return row2;
}

- (__kindof YIFormRow *)rowWithTitle:(NSString *)title tag:(NSString *)tag {
    //    YIFormRowText *row00 = Row(YIFormRowText.class);
    //    row00.height = arc4random()%50 + 10;
    //    row00.title = [NSString stringWithFormat:@"%@ height:%.2f",title, row00.height];
    //    Row(YIAttachFormRow.class)
    __weak typeof(self) weakSelf = self;
    YIAttachFormRow *row = [YIAttachFormRow row];
    row.tag = tag;
    row.title = title;
    row.containerBackgroundColor = [UIColor orangeColor];
    row.previewBlock = ^(NSURL *fileURL) {
    };
    
    row.uploadBlock = ^(NSURL *fileURLs) {
    };
    
    row.selectionHandler = ^(__kindof YIFormRow * _Nonnull item) {
        NSLog(@"selectionHandler");
    };
    
    return row;
}
- (__kindof YIFormRow *)rowWithTitle:(NSString *)title specialCellClass:(id)cellClass {
    //    YIFormRowText *row00 = Row(YIFormRowText.class);
    //    row00.height = arc4random()%50 + 10;
    //    row00.title = [NSString stringWithFormat:@"%@ height:%.2f",title, row00.height];
    //    Row(YIAttachFormRow.class)
    __weak typeof(self) weakSelf = self;
    YIAttachFormRow *row = [YIAttachFormRow rowWithCellClass:cellClass];
    row.title = title;
    row.containerBackgroundColor = [UIColor whiteColor];
//    row.containerBackgroundColor = [UIColor orangeColor];
    row.previewBlock = ^(NSURL *fileURL) {
    };
    
    row.uploadBlock = ^(NSURL *fileURLs) {
    };
    
    row.selectionHandler = ^(__kindof YIFormRow * _Nonnull item) {
        NSLog(@"selectionHandler");
    };
    
    return row;
}
- (void)accessoryButtonAction:(id)sender {
    __weak typeof(self) weakSelf = self;
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"點(diǎn)擊" message:[NSString stringWithFormat:@"Hello,你點(diǎn)到我了"] preferredStyle:UIAlertControllerStyleAlert];
    
    // Create the actions.
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        YIMessageViewController *viewController = [[YIMessageViewController alloc] init];
        [viewController showOnViewController:weakSelf];
    }];
    // Add the actions.
    [alertController addAction:okAction];
    [alertController addAction:cancelAction];
    [self.navigationController presentViewController:alertController animated:YES completion:nil];
}


- (void)showAlert:(YIFormRow *)item {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Confirmation" message:[NSString stringWithFormat:@"Are you sure you want to delete %@", item.title] preferredStyle:UIAlertControllerStyleAlert];
    
    // Create the actions.
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        if (self.deleteConfirmationHandler) {
            self.deleteConfirmationHandler();
            NSLog(@"Item removed: %@", self.itemToDelete.title);
        }
    }];
    // Add the actions.
    [alertController addAction:okAction];
    [alertController addAction:cancelAction];
    [self.navigationController presentViewController:alertController animated:YES completion:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (UITableView *)tableView {
    if (!_tableView) {
        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
        _tableView = tableView;
    }
    return _tableView;
}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市留特,隨后出現(xiàn)的幾起案子纠脾,更是在濱河造成了極大的恐慌,老刑警劉巖蜕青,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苟蹈,死亡現(xiàn)場離奇詭異,居然都是意外死亡右核,警方通過查閱死者的電腦和手機(jī)慧脱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贺喝,“玉大人菱鸥,你說我怎么就攤上這事□镉悖” “怎么了氮采?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長染苛。 經(jīng)常有香客問我鹊漠,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任躯概,我火速辦了婚禮登钥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘楞陷。我一直安慰自己怔鳖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布固蛾。 她就那樣靜靜地躺著结执,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艾凯。 梳的紋絲不亂的頭發(fā)上献幔,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音趾诗,去河邊找鬼蜡感。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恃泪,可吹牛的內(nèi)容都是我干的郑兴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼贝乎,長吁一口氣:“原來是場噩夢啊……” “哼情连!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起览效,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤却舀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后锤灿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽拔,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年但校,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了螃诅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡状囱,死狀恐怖州刽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浪箭,我是刑警寧澤穗椅,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站奶栖,受9級(jí)特大地震影響匹表,放射性物質(zhì)發(fā)生泄漏门坷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一袍镀、第九天 我趴在偏房一處隱蔽的房頂上張望默蚌。 院中可真熱鬧,春花似錦苇羡、人聲如沸绸吸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锦茁。三九已至,卻和暖如春叉存,著一層夾襖步出監(jiān)牢的瞬間码俩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工歼捏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稿存,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓瞳秽,卻偏偏與公主長得像瓣履,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子练俐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月袖迎,有人笑有人哭,有人歡樂有人憂愁痰洒,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,529評(píng)論 28 53
  • 信任包括信任自己和信任他人 很多時(shí)候浴韭,很多事情丘喻,失敗、遺憾念颈、錯(cuò)過泉粉,源于不自信,不信任他人 覺得自己做不成榴芳,別人做不...
    吳氵晃閱讀 6,186評(píng)論 4 8
  • 怎么對(duì)待生活窟感,它也會(huì)怎么對(duì)你 人都是哭著來到這個(gè)美麗的人間讨彼。每個(gè)人從來到塵寰到升入天堂,整個(gè)生命的歷程都是一本書柿祈,...
    靜靜在等你閱讀 4,962評(píng)論 1 6