iOS上的简单表单。
用于Firehose Chat iOS应用程序中。
要尝试一下,使用--recursive
克隆此库,并打开演示应用程序,展示了几种不同类型的表单和表单元素。
iOS 7+
MYSForms允许您轻松地在iOS上构建表单进行展示。表单绑定到模型,可以是任何对象、字典,甚至是[NSUserDefaults standardUserDefaults]
。您可以验证您的表单,显示错误/成功/加载消息等。
MYSForms基于UICollectionViewController
。这意味着它们非常灵活且可定制。这也意味着在使用应用程序时它们极其容易使用。您只需创建一个MYSFormViewController
实例,进行配置,然后再像任何其他视图控制器一样展示即可。或者,你可以继承MYSFormViewController
并展示您的子类。
要配置表单,您只需向其中添加MYSFormElement
对象即可。就是这样。
表单是
创建表单有两种方式
MYSFormViewController
实例并向其中添加表单元素。MYSFormViewController
的子类,并覆盖configureForm
方法,在那里添加表单元素。如果您在使用故事板,使用继承方法更为合适。只需将一个 UICollectionViewController
拖拽到您的故事板上,并将视图控制器的类设置为您的自定义子类。当应用切换到该场景(派生自 MYSFormViewController
)时,表单将会出现并自动执行。
表单是一个包含 MYSFormElement
子类对象数组的 MYSFormViewController
。每个 MYSFormElement
子类代表不同的表单元素,如标题、描述性文本、文本框、文本视图、选择器、切换按钮、图片选择器等。
MYSForms提供大量可以使用的 MYSFormElement
子类,您也可以创建自己的或进一步派生现有的类来调整它们的样式和行为。
验证是您可以添加到表单元素中的对象,以确保这些元素的值有效。如果值无效,它会在表单元素旁边自动显示验证错误,解释问题,用户可以据此进行修正。MYSForms提供一些标准的验证类,如确保值非空或确保值符合特定格式。验证对象是 MYSFormValidation
的子类。
由于每个可编辑的表单元素可能会绑定到模型上的一个属性,您可能想给元素添加一个转换器,以便当从模型读取模型值时,它可以转换为适用于视觉显示的类型。同样,当用户更改值时,您的转换器可以将视觉形式转换为模型期望的类型。转换器是 NSValueTransformer
的子类。
假设我们想通过创建 MYSFormViewController
的实例并向其中添加一些表单元素来创建一个表单
// create an instance of MYSFormViewController
MYSFormViewController *formViewController = [MYSFormViewController new];
// setting the model
formViewController.model = self.fakeUser;
// add a header element
MYSFormLabelElement *headline = [MYSFormLabelElement labelElementWithText:@"Log In"];
[formViewController addFormElement:headline];
// add a text field for the user to type in an email
MYSFormTextFieldElement *emailField = [MYSFormTextFieldElement textFieldElementWithLabel:@"E-mail" modelKeyPath:@"email"];
emailField.keyboardType = UIKeyboardTypeEmailAddress;
[formViewController addFormElement:emailField];
// push the form onto the navigation stack and that's it!
[self.navigationController pushViewController:formViewController animated:YES];
第二种,更稳健的方法,您可以像这样继承 MYSFormViewController
MYSSignUpFormViewController.h
#import "MYSForms.h"
@interface MYSSignUpFormViewController : MYSFormViewController
@end
MYSSignUpFormViewController.m
#import "MYSSignUpFormViewController.h"
#import "MYSExampleUser.h"
@implementation MYSSignUpFormViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.model = [MYSExampleUser new];
}
- (void)configureForm
{
[super configureForm];
[self addFormElement:[MYSFormLabelElement labelElementWithText:@"Sign Up"]];
[self addFormElement:[MYSFormLabelElement labelElementWithText:
@"Example of a subclassed form view controller where a blank model is created in its viewDidLoad."]];
[self addFormElement:[MYSFormTextFieldElement textFieldElementWithLabel:@"First Name" modelKeyPath:@"firstName"]];
[self addFormElement:[MYSFormTextFieldElement textFieldElementWithLabel:@"Last Name" modelKeyPath:@"lastName"]];
MYSFormTextFieldElement *emailField = [MYSFormTextFieldElement textFieldElementWithLabel:@"E-mail" modelKeyPath:@"email"];
emailField.keyboardType = UIKeyboardTypeEmailAddress;
[self addFormElement:emailField];
MYSFormTextFieldElement *passwordField = [MYSFormTextFieldElement textFieldElementWithLabel:@"Password" modelKeyPath:@"password"];
passwordField.secure = YES;
[self addFormElement:passwordField];
}
一个带验证的电子邮件字段的示例
MYSFormTextFieldElement *emailField = [MYSFormTextFieldElement textFieldElementWithLabel:@"E-mail" modelKeyPath:@"email"];
emailField.keyboardType = UIKeyboardTypeEmailAddress;
[emailField addFormValidation:[MYSFormPresenceValidation new]];
[emailField addFormValidation:[MYSFormRegexValidation regexValidationWithName:MYSFormRegexValidationPatternEmail]];
[self addFormElement:emailField];
在这里我们添加了一个当点击时显示 UIPickerView
的表单元素。使用值转换器将模型的 NSNumber
值转换为 NSString
以供选择器元素显示。
MYSFormPickerElement *pickerElement = [MYSFormPickerElement pickerElementWithLabel:@"Age" modelKeyPath:@"yearsOld"];
pickerElement.valueTransformer = [MYSFormStringFromNumberValueTransformer new];
for (NSInteger i = 0; i < 120; i++) {
[pickerElement addValue:@(i)];
}
[self addFormElement:pickerElement];
在特定的表单元素下方显示一个错误消息
[self addFormElement:[MYSFormLabelAndButtonElement buttonElementWithLabel:@"A label" title:@"And button" block:^(MYSFormButtonElement *element) {
[self showErrorMessage:@"An error message." belowElement:element duration:3 completion:nil];
}]];
在特定的表单元素下方显示一个成功消息
[self addFormElement:[MYSFormButtonElement buttonElementWithTitle:@"Button" block:^(MYSFormElement *element) {
[self showSuccessMessage:@"A success message." belowElement:element duration:3 completion:nil];
}]];
在特定的表单元素上方显示一个加载消息
[self addFormElement:[MYSFormButtonElement buttonElementWithTitle:@"Show Loading Specific" block:^(MYSFormElement *element) {
[self showLoadingMessage:@"Loading for a specific form element." aboveElement:self.firstNameElement completion:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self hideLoadingAboveElement:self.firstNameElement completion:nil];
});
}]];
有两种方式来自定义表单
MYSFormTheme
MYSFormTheme
您可以为 MYSFormTheme
创建一个新的实例,调整该对象的属性,然后将其分配给任何 MYSFormElement
。如果您在主题上自定义了标签字体/颜色属性,那么赋予该主题的任何元素的标签都将应用这些自定义。
您还可以将主题分配给整个表单,该主题随后将传递到所有元素中。元素主题上设置的属性将覆盖传递给元素的表单主题。例如,如果您在两个不同的主题上设置了 tintColor
属性,将一个分配给表单,另一个分配给一个元素,则该元素将使用直接分配给它的主题上的 tintColor
。
以下是一个设置表单主题上某些属性(在 self.theme
上设置)和分配给一个元素的主题的示例
- (void)configureForm
{
[super configureForm];
// set a form-wide theme
self.theme = [MYSFormTheme new];
self.theme.buttonStyle = @(MYSFormButtonStyleFilled);
self.theme.labelFont = [UIFont fontWithName:@"Avenir" size:12];
self.theme.inputTextFont = [UIFont fontWithName:@"Noteworthy" size:14];
MYSFormLabelElement *headlineElement = [MYSFormLabelElement labelElementWithText:@"A Headline"];
headlineElement.theme = [MYSFormTheme formThemeWithLabelFont:[UIFont fontWithName:@"Zapfino" size:26]];
[self addFormElement:headlineElement];
}
根据您想要多疯狂,您可以继承整个元素、仅继承其单元格或仅替换其 xib 以您的自定义版本。如果您只想改变单元格的自动布局方式或移动元素单元格中的视图,仅替换 xib 以您的自定义版本即可。如果您想自定义动画、行为或基于内容计算高度,那么您将想要继承元素的单元格。如果您继承了一个单元格,您还必须用您自己的替换 xib。以下介绍如何继承一个元素的单元格
假设您想自定义表头元素的外观。您可以像这样继承 MYSFormHeadlineCell.h
FCIFormHeaderCell.h
#import <MYSForms.h>
@interface FCIFormHeaderCell : MYSFormHeadlineCell
@end
FCIFormHeaderCell.m
#import "FCIFormHeaderCell.h"
@implementation FCIFormHeaderCell
+ (CGSize)sizeRequiredForElement:(MYSFormElement *)element width:(CGFloat)width
{
return CGSizeMake(width, 100);
}
@end
然后,在您实际提供 UI 的地方
FCIFormHeaderCell.xib
技巧是确保您的 xib 中视图的 outlets 连接到 MYSFormHeadlineCell
超类的属性。
YourFormViewController.m
- (void)configureForm
{
[super configureForm];
MYSFormHeadlineElement *headlineElement = [labelElementWithText labelElementWithText:@"Sign Up"];
headlineElement.cellClass = [FCIFormHeaderCell class];
[self addFormElement:headlineElement];
}
就是这样。为了总结
FCIFormHeaderCell
类,该类继承自 MYSFormHeadlineCell
。登录表单和注册表单
验证错误和加载消息
其他元素示例
还有一个名为 MYSFormSlideViewController
的 MYSFormViewController
子类,它是 MYSForms 的一部分,当显示时,将从底部滑出表单。
如果您使用 MYSCollectionView 并使用 MYSCollectionViewSpringyLayout
,您将获得一种有趣的弹簧效果,在表单中的元素之间。
使用 --recursive
克隆仓库,因为有一些重要的子模块需要包含在内。
在提交 pull 请求之前,请更新并运行测试。谢谢。
查看Firehose Chat,并将免费聊天框添加到您的网站,以便与访客进行聊天。当访客想要聊天时,即使您处于离线状态,您也会收到推送通知。您可以通过iOS应用或Mac应用立即进行回复。