PAYFormBuilder 3.0.0

PAYFormBuilder 3.0.0

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布最新发布2015年12月

Simon SeyerSimon SeyerKai S.维护。



 
依赖
libextobjc~> 0.4
SZTextView~> 1.1
 


  • Simon Seyer

FormBuilder 是一个库,用于通过简单的方式创建 iOS 7/8 的通用屏幕。凭借其基于块的语法和广泛的定制可能性,创建表单非常有趣。

特性

  • 简单语法 - 使用块语法,您的代码结构良好且易于理解
  • 预定义样式 - 获得无缝的 iOS 7/8 感受,而无需编写一行样式代码
  • 验证 - 使用默认的验证处理和错误消息管理
  • 可定制 - 改变 PAYFormBuilder 为您配置的任何内容 - 仅注册一些块并等待回调
  • 主题化 - 您决定表单看起来如何
  • 自适应布局兼容 - 为了最大灵活性,所有元素都使用自动布局定位
  • 示例应用 - 了解库的所有可能性和如何充分利用它

结构

以下简短的 objective-c-pseudo-code 结构概述应能为您提供一个如何使用 FormBuilder 的工作思路。

@class YourTableViewController : PAYFormTableViewController

- loadStructure: tableBuilder {
  [tableBuilder addSection:^(sectionBuilder){
    [sectionBuilder addRow]
    [sectionBuilder addRow]
  }]
  [tableBuilder addSection:^(sectionBuilder){
    [sectionBuilder addRow]
  }]
}

使用

为了创建表单屏幕,您必须继承自 PAYFormTableViewController 并实现 loadStructure: 方法。您应在这个方法中完成所有配置。

#import "PAYFormBuilder.h"

@interface YourViewController : PAYFormTableViewController

@end
#import "YourViewController.h"

@implementation YourViewController

- (void)loadStructure:(PAYFormTableBuilder *)tableBuilder {
    // Build your form here   
}

@end

部分

使用 tableBuilder,您可以为表单添加部分并进行一些整体配置。为了添加部分,请使用以下方法或其便捷的变体之一。

- (PAYFormSection *)addSectionWithName:(NSString *)name 
                            labelStyle:(PAYFormTableLabelStyle)style 
                           headerBlock:(void(^)(PAYFormHeader *))headerBlock 
                          contentBlock:(void(^)(PAYFormSectionBuilder *)contentBlock

最重要的参数是 contentBlock,它是定义为 ^(PAYFormSectionBuilder *sectionBuilder) 的。在这个块中,您可以添加字段、按钮等(请参阅行部分)。

使用 sectionBuilder,您有一个用于创建多种不同行类型的工厂对象。存在预定义的方法来创建

  • 文本字段
  • 文本视图
  • 按钮
  • 按钮组(连接的按钮列表)
  • 开关

但是,也存在可以在 sectionBuilder 上调用的通用 addView: 方法,其中您可以获得一个空的 PAYFormView,它仅包含一个您可以自己配置的表视图单元格。请注意,对于所有行类型,都有可以传递 configureBlock 的工厂方法,因此您始终可以根据自己的喜好更改它们。

错误处理

在库中,有两种错误处理方式。这两种方式都是基于 NSError 错误代码的。对于内置验证函数,这些列在 PAYErrorCodes.h 文件中。对于您的自定义验证,您在抛出错误时定义它们。

  • 自定义:只需设置 PAYFormBuilderformFailBlock。当用户完成后表单且存在错误时,您将会收到通知。为了 区分不同的错误,请使用 NSError 中的错误代码。
  • 自动:默认情况下,自动错误处理被激活,当用户犯错时,会向用户显示错误提示。您可以通过以下方式配置此错误处理器:

    • PAYFormView 类或其子类(例如 PAYFormFieldPAYFormButton 等)上调用

      • PAYFormDefaultErrorHandler 类中的 setErrorMessage:forErrorCode:
      • PAYFormDefaultErrorHandler 类上
      • 实例或其子类(如 PAYFormView 类的实例)的 PAYFormView 或其子类

      错误消息优先级的规则是:类/实例越具体,优先级越高。实例的优先级高于类。错误消息的类型为 PAYFormErrorMessage。查看类的初始化函数来了解创建错误消息的不同方法。

    • PAYFormDefaultErrorHandler 类上调用 setButtonText: 来配置关闭提示的按钮。这一步是必需的

自定义文本协议者

框架会设置包装的 UITextFieldUITextView 的协议,以支持验证和格式特性。要添加自定义协议者,只需将其设置为 ViewHolder(例如 PayFormSingleLineTextField)的 delegate。如果 maxTextLength 验证约束成功,您的协议者将会使用格式化后的文本执行。

主题化

只需查看 utils/theming 文件夹,即可查看可用的主题容器和样式属性。您可以实现 PAY*Theme 协议之一来替换任何主题,并将它们设置为 PAYStyle 类。然而,最简单的方法是从 PAYStyle 类获取主题并调整不同的属性。

ważne 是在创建表单之前进行主题化。所有样式都是在表单初始化时应用的,因此之后无法更新它们。

布局自定义

在创建元素时,每个容器对象(例如 PAYFormButtonPAYFormSingleLineTextFieldPAYFormHeader 等)都包含一个 NSLayoutConstraint 属性列表,允许您调整布局。只需更改属性,禁用或删除约束即可。

约束属性以添加约束的视图的名称为前缀。例如,约束属性 viewControlBottomConstraint 被添加到容器的 view 属性,并约束控制器的底部间距。

示例

创建注册表单是应用程序开发的常见任务,因此这里使用它作为示例,展示一些 PAYFormBuilder 的可能性。要获得所有功能的概述,请运行示例应用程序。

#import <UIKit/UIKit.h>
#import "PAYFormBuilder.h"

@interface PAYRegistrationFormViewController : PAYFormTableViewController

@end
#import "PAYRegistrationFormViewController.h"

@interface PAYRegistrationFormViewController ()

@property (nonatomic, retain) PAYFormSingleLineTextField *userNameField;
@property (nonatomic, retain) PAYFormSingleLineTextField *passwordField1;
@property (nonatomic, retain) PAYFormSingleLineTextField *passwordField2;

@property (nonatomic, retain) PAYFormSingleLineTextField *streetTextField;
@property (nonatomic, retain) PAYFormSingleLineTextField *postalCodeTextField;
@property (nonatomic, retain) PAYFormSingleLineTextField *cityTextField;

@property (nonatomic, retain) PAYFormButtonGroup *countryButtonGroup;
@property (nonatomic, retain) PAYFormSwitch *formSwitch;

@end

@implementation PAYRegistrationFormViewController


- (void)loadStructure:(PAYFormTableBuilder *)tableBuilder {
    [tableBuilder addSectionWithName:nil
                          labelStyle:PAYFormTableLabelStyleNone
                        contentBlock:^(PAYFormSectionBuilder *sectionBuilder) {
        self.userNameField = [sectionBuilder addFieldWithName:@"Username" placeholder:@"your username"
                                               configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                   formField.required = YES;
                                                   formField.minTextLength = 4;
                                               }];

        self.passwordField1 = [sectionBuilder addFieldWithName:@"Password" placeholder:@"your password"
                                                configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                    [formField activateSecureInput];
                                                }];
        self.passwordField2 = [sectionBuilder addFieldWithName:@"Password 2" 
                                                   placeholder:@"repeat your password"
                                                configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                    [formField activateSecureInput];
                                                }];
    }];

    [tableBuilder addSectionWithName:@"Country"
                          labelStyle:PAYFormTableLabelStyleSimple
                        contentBlock:^(PAYFormSectionBuilder *sectionBuilder) {
                            self.countryButtonGroup = [sectionBuilder addButtonGroupWithMutliSelection:NO
                                contentBlock:^(PAYFormButtonGroupBuilder *^buttonGroupBuilder) {
                                    NSArray *countries = @[
                                            @[@"United States", @"usa"], 
                                            @[@"Germany", @"de"], 
                                            @[@"Spain", @"es"]
                                    ];
                                    for (NSArray *country in countries) {
                                        [buttonGroupBuilder addOption:country[1] 
                                                              withText:country[0] 
                                                                  icon:[UIImage imageNamed:country[1]]];
                                    }
                                    [buttonGroupBuilder select:@"usa"];
                                }];
                            [self.countryButtonGroup select:YES value:@"usa"];
                        }];

    [tableBuilder addSectionWithName:@"Address"
                          labelStyle:PAYFormTableLabelStyleSimple
                        contentBlock:^(PAYFormSectionBuilder *sectionBuilder) {
        self.streetTextField = [sectionBuilder addFieldWithName:@"Street" placeholder:@"your street"
                                                 configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                     formField.required = YES;
                                                     formField.expanding  = YES;
                                                 }];

        self.postalCodeTextField = [sectionBuilder addFieldWithName:@"Postal code" 
                                                        placeholder:@"your postal code"
                                                     configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                         formField.required = YES;
                                                         formField.cleanBlock = ^id(PAYFormField *formField, id value) {
                                                             NSString *strValue = value;
                                                             return [strValue stringByReplacingOccurrencesOfString:@" " 
                                                                                                        withString:@""];
                                                         };
                                                     }];
        self.cityTextField = [sectionBuilder addFieldWithName:@"City" placeholder:@"your city"
                                               configureBlock:^(PAYFormSingleLineTextField *formField) {
                                                   formField.required = YES;
                                               }];
    }];



    [tableBuilder addSectionWithName:@"Terms and Conditions" 
                        contentBlock:^(PAYFormSectionBuilder *sectionBuilder) {
        self.formSwitch = [sectionBuilder addSwitchWithName:@"Accept"
                                             configureBlock:^(PAYFormSwitch *formSwitch) {
            formSwitch.required = YES;

           [formSwitch setErrorMessage:[PAYFormErrorMessage errorMessageWithTitle:@"Accept"
                                                                          message:@"Please accept the terms and conditions to continue"]
                          forErrorCode:PAYFormMissingErrorCode];
                                             }];
    }];

    tableBuilder.finishOnLastField = YES;
    tableBuilder.selectFirstField = YES;

    tableBuilder.validationBlock =  ^NSError *{
        if (![self.passwordField1.value isEqualToString:self.passwordField2.value]) {
            return [NSError validationErrorWithTitle:@"Password wrong" 
                                             message:@"Please enter the same password again" 
                                             control:self.passwordField2];
        }
        return nil;
    };

    tableBuilder.formSuccessBlock = ^{
        NSString *msg = [NSString stringWithFormat:@"Well done, %@. Here your cleaned postal code: %@. Country code: %@",
                         self.userNameField.value, self.postalCodeTextField.cleanedValue, self.countryButtonGroup.value];

        UIAlertView *alertView  = [[UIAlertView alloc]initWithTitle:@"Success"
                                                            message:msg
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles: nil];
        [alertView show];
    };
}


@end

安装

源代码文件

  1. 将存储库添加为 Git 子模块到您的 Git 跟踪项目中。
  2. 将存档中的 PAYFormBuilder 目录拖放到项目导航器中。如果在项目外部提取了代码存档,确保选择 复制项目
  3. 在需要任何组件的地方包含 PAYFormBuilder,使用 #import "PAYFormBuilder.h"

静态库

  1. PAYFormBuilder.xcodeproj 拖放到项目导航器中。
  2. 选择您的目标,转到 构建阶段 选项卡。在 链接二进制与库 部分,选择添加按钮。在对话框中找到并添加 libPAYFormBuilder.a。
  3. 将目标 PAYFormBuilder 添加到您的 目标依赖 列表中。
  4. 在需要使用组件的地方使用 import <PAYFormBuilder/PAYFormBuilder.h>。如果您希望,还可以将其添加到前缀头文件中。

迁移

1.x -> 2.x

  • PAYFormButton 现在有一个 label 属性,而不是 titleLabel
  • PAYFormView(及其子类 PAYFormButtonPAYFormSingleLineTextField 等)现在有一个 cell 属性,允许配置或替换单元格。仍然使用 view 属性添加子视图。
  • PAYFormButtonStyle 的名称已经被更改
  • 所有框架计算都被自动布局替代,因此不应再手动设置框架
  • 应移除 initWithFrame: 调用
  • 使用全新的主题 API 来设置您表单的样式

要求

  • iOS 7+
  • ARC
  • BlocksKit
  • libextobjc
  • SZTextView