Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9de49db86 | |||
| 77db6b9492 | |||
| 74b26c1e64 | |||
| 085cf31e52 | |||
| 313e5d5d40 | |||
| f7777d9d27 | |||
| 578dea99dd | |||
| 1da30107dc | |||
| 4674c3abaf | |||
| 5ca54fd949 | |||
| e64e5b4885 |
+1
-1
@@ -1,5 +1,5 @@
|
||||
language: objective-c
|
||||
osx_image: xcode7.2
|
||||
osx_image: xcode8.2
|
||||
before_install:
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
|
||||
@@ -57,6 +57,7 @@ NSString *const kCountDownTimer = @"countDownTimer";
|
||||
// Date
|
||||
row = [XLFormRowDescriptor formRowDescriptorWithTag:kDateInline rowType:XLFormRowDescriptorTypeDateInline title:@"Date"];
|
||||
row.value = [NSDate new];
|
||||
[row.cellConfigAtConfigure setObject:[NSLocale localeWithLocaleIdentifier:@"FR_fr" ] forKey:@"locale"];
|
||||
[section addFormRow:row];
|
||||
|
||||
// Time
|
||||
|
||||
@@ -105,6 +105,11 @@
|
||||
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
|
||||
[section addFormRow:row];
|
||||
|
||||
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"megabytes" rowType:XLFormRowDescriptorTypeInfo title:@"Megabytes"];
|
||||
row.valueFormatter = [NSByteCountFormatter new];
|
||||
row.value = @(1024);
|
||||
[section addFormRow:row];
|
||||
|
||||
section = [XLFormSectionDescriptor formSection];
|
||||
[formDescriptor addFormSection:section];
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ class DatesFormViewController: XLFormViewController {
|
||||
// Date
|
||||
row = XLFormRowDescriptor(tag: Tags.DateInline, rowType: XLFormRowDescriptorTypeDateInline, title:"Date")
|
||||
row.value = Date()
|
||||
row.cellConfigAtConfigure["locale"] = Locale(identifier: "FR_fr")
|
||||
section.addFormRow(row)
|
||||
|
||||
// Time
|
||||
|
||||
@@ -6,7 +6,7 @@ By [XMARTLABS](http://xmartlabs.com).
|
||||
[](https://travis-ci.org/xmartlabs/XLForm)
|
||||
<a href="https://cocoapods.org/pods/XLForm"><img src="https://img.shields.io/cocoapods/v/XLForm.svg" alt="CocoaPods compatible" /></a>
|
||||
|
||||
**If you are looking for Swift native implementation we have recently created [Eureka], a complete re-design of XLForm in Swift.** *Do not panic, We will continue maintaining and improving XLForm, obj-c rocks!!*
|
||||
**If you are working in Swift then you should have a look at [Eureka], a complete re-design of XLForm in Swift.** *Do not panic, we will continue maintaining and improving XLForm, obj-c rocks!!*
|
||||
|
||||
Purpose
|
||||
--------------
|
||||
@@ -15,7 +15,7 @@ XLForm is the most flexible and powerful iOS library to create dynamic table-vie
|
||||
|
||||
XLForm provides a very powerful DSL (Domain Specific Language) used to create a form. It keeps track of this specification on runtime, updating the UI on the fly.
|
||||
|
||||
#####Let's see the iOS Calendar Event Form created using XLForm
|
||||
##### Let's see the iOS Calendar Event Form created using XLForm
|
||||
|
||||
|
||||

|
||||
@@ -182,7 +182,7 @@ How to run XLForm examples
|
||||
|
||||
Rows
|
||||
---------------------
|
||||
####Input Rows
|
||||
#### Input Rows
|
||||
|
||||

|
||||
|
||||
@@ -253,7 +253,7 @@ Will be represented by a `UITextView` with `UITextAutocorrectionTypeDefault`, `U
|
||||
|
||||
|
||||
|
||||
####Selector Rows
|
||||
#### Selector Rows
|
||||
|
||||
Selector rows allow us to select a value or values from a list. XLForm supports 8 types of selectors out of the box:
|
||||
|
||||
@@ -320,7 +320,7 @@ This is the protocol declaration:
|
||||
```
|
||||
|
||||
|
||||
####Date & Time Rows
|
||||
#### Date & Time Rows
|
||||
|
||||
XLForms supports 3 types of dates: `Date`, `DateTime` , `Time` and `Countdown Timer` and it's able to present the `UIDatePicker` control in 2 different ways, inline and non-inline.
|
||||
|
||||
@@ -427,7 +427,7 @@ section.addFormRow(row)
|
||||
self.form = form;
|
||||
|
||||
```
|
||||
####Boolean Rows
|
||||
#### Boolean Rows
|
||||
|
||||
XLForms supports 2 types of boolean controls:
|
||||
|
||||
@@ -445,9 +445,9 @@ static NSString *const XLFormRowDescriptorTypeBooleanSwitch = @"booleanSwitch";
|
||||
We can also simulate other types of Boolean rows using any of the Selector Row Types introduced in the [Selector Rows section](#selector-rows).
|
||||
|
||||
|
||||
####Other Rows
|
||||
#### Other Rows
|
||||
|
||||
#####Stepper
|
||||
##### Stepper
|
||||
|
||||
XLForms supports counting using UIStepper control:
|
||||
|
||||
@@ -469,7 +469,7 @@ You can set the stepper paramaters easily:
|
||||
[row.cellConfigAtConfigure setObject:@100 forKey:@"stepControl.maximumValue"];
|
||||
```
|
||||
|
||||
#####Slider
|
||||
##### Slider
|
||||
|
||||
XLForms supports counting using UISlider control:
|
||||
|
||||
@@ -490,11 +490,11 @@ You can adjust the slider for your own interests very easily:
|
||||
|
||||
Set `steps` to `@(0)` to disable the steps functionality.
|
||||
|
||||
#####Info
|
||||
##### Info
|
||||
|
||||
Sometimes our apps needs to show data that are not editable. XLForm provides us with `XLFormRowDescriptorTypeInfo` row type to display not editable info. An example of usage would be showing the app version in the settings part of an app.
|
||||
|
||||
#####Button
|
||||
##### Button
|
||||
|
||||
Apart from data entry rows, not editable rows and selectors, XLForm has a button row `XLFormRowDescriptorTypeButton` that allows us to do any action when selected. It can be configured using a block (clousure), a selector, a segue identifier, segue class or specifing a view controller to be presented. ViewController specification could be done by setting up the view controller class, the view controller storyboard Id or a nib name. Nib name must match view controller class name.
|
||||
|
||||
@@ -767,7 +767,7 @@ For instance if we want to show or hide a row depending on the value of another
|
||||
Make a row or section invisible depending on other rows values
|
||||
--------------------------------
|
||||
|
||||
###Summary
|
||||
### Summary
|
||||
|
||||
XLForm allows you to define dependencies between rows so that if the value of one row is changed, the behaviour of another one changes automatically. For example, you might have a form where you question the user if he/she has pets. If the answer is 'yes' you might want to ask how their names are.
|
||||
So you can make a row invisible and visible again based on the values of other rows. The same happens with sections.
|
||||
@@ -777,7 +777,7 @@ Take a look at the following example:
|
||||
|
||||
Of course, you could also do this manually by observing the value of some rows and deleting and adding rows accordingly, but that would be a lot of work which is already done.
|
||||
|
||||
###How it works
|
||||
### How it works
|
||||
|
||||
To make the appearance and disappearance of rows and sections automatic, there is a property in each descriptor:
|
||||
|
||||
@@ -897,6 +897,25 @@ section.addFormRow(row)
|
||||
FAQ
|
||||
-------
|
||||
|
||||
#### How to customize the header and/or footer of a section
|
||||
|
||||
For this you should use the UITableViewDelegate methods in your XLFormViewController.
|
||||
This means you should implement one or both of these:
|
||||
|
||||
```objc
|
||||
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
|
||||
|
||||
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
|
||||
```
|
||||
|
||||
Also you might want to implement the following methods to specify the height for these views:
|
||||
|
||||
```objc
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
|
||||
|
||||
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
|
||||
```
|
||||
|
||||
#### How to assign the first responder on form appearance
|
||||
|
||||
Assign the first responder when the form is shown is as simple as setting the property `assignFirstResponderOnShow` to `YES`. By default the value of the property is `NO`.
|
||||
@@ -1008,7 +1027,7 @@ row.cellConfig.setObject(UIFont(name: "AppleSDGothicNeo-Regular", size: 17)!, fo
|
||||
|
||||
For further details, please take a look at [UICustomizationFormViewController.m](/Examples/Objective-C/Examples/UICustomization/UICustomizationFormViewController.m) example.
|
||||
|
||||
####How to set min/max for date cells?
|
||||
#### How to set min/max for date cells?
|
||||
|
||||
Each XLFormDateCell has a `minimumDate` and a `maximumDate` property. To set a datetime row to be a value in the next three days you would do as follows:
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ include FileUtils::Verbose
|
||||
namespace :test do
|
||||
desc "Run the XLForm Tests"
|
||||
task :ios do
|
||||
run_tests('XLForm Tests', 'iphonesimulator9.2')
|
||||
run_tests('XLForm Tests', 'iphonesimulator10.2')
|
||||
tests_failed unless $?.success?
|
||||
end
|
||||
end
|
||||
@@ -17,7 +17,7 @@ task :default => 'test'
|
||||
private
|
||||
|
||||
def run_tests(scheme, sdk)
|
||||
sh("xcodebuild -workspace 'Tests/XLForm Tests.xcworkspace' -scheme '#{scheme}' -sdk '#{sdk}' -destination 'name=iPhone 6' -configuration Release clean test | xcpretty -c ; exit ${PIPESTATUS[0]}") rescue nil
|
||||
sh("xcodebuild -workspace 'Tests/XLForm Tests.xcworkspace' -scheme '#{scheme}' -sdk '#{sdk}' -destination 'OS=10.1,name=iPhone 7' -configuration Release clean test | xcpretty -c ; exit ${PIPESTATUS[0]}") rescue nil
|
||||
end
|
||||
|
||||
def tests_failed
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
@implementation XLFormDateCell
|
||||
{
|
||||
UIColor * _beforeChangeColor;
|
||||
NSDateFormatter *_dateFormatter;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +110,7 @@
|
||||
{
|
||||
[super configure];
|
||||
self.formDatePickerMode = XLFormDateDatePickerModeGetFromRowDescriptor;
|
||||
_dateFormatter = [[NSDateFormatter alloc] init];
|
||||
}
|
||||
|
||||
-(void)update
|
||||
@@ -173,10 +175,14 @@
|
||||
}
|
||||
}
|
||||
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDate] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateInline]){
|
||||
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle];
|
||||
_dateFormatter.dateStyle = NSDateFormatterMediumStyle;
|
||||
_dateFormatter.timeStyle = NSDateFormatterNoStyle;
|
||||
return [_dateFormatter stringFromDate:date];
|
||||
}
|
||||
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTime] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTimeInline]){
|
||||
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterNoStyle timeStyle:NSDateFormatterShortStyle];
|
||||
_dateFormatter.dateStyle = NSDateFormatterNoStyle;
|
||||
_dateFormatter.timeStyle = NSDateFormatterShortStyle;
|
||||
return [_dateFormatter stringFromDate:date];
|
||||
}
|
||||
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimer] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimerInline]){
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
@@ -184,7 +190,9 @@
|
||||
NSDateComponents *time = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
|
||||
return [NSString stringWithFormat:@"%ld%@ %ldmin", (long)[time hour], (long)[time hour] == 1 ? @"hour" : @"hours", (long)[time minute]];
|
||||
}
|
||||
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle];
|
||||
_dateFormatter.dateStyle = NSDateFormatterShortStyle;
|
||||
_dateFormatter.timeStyle = NSDateFormatterShortStyle;
|
||||
return [_dateFormatter stringFromDate:date];
|
||||
}
|
||||
|
||||
-(void)setModeToDatePicker:(UIDatePicker *)datePicker
|
||||
@@ -228,6 +236,11 @@
|
||||
return _datePicker;
|
||||
}
|
||||
|
||||
-(void)setLocale:(NSLocale *)locale
|
||||
{
|
||||
_locale = locale;
|
||||
_dateFormatter.locale = locale;
|
||||
}
|
||||
|
||||
#pragma mark - Target Action
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
return tranformedValue;
|
||||
}
|
||||
}
|
||||
return [self.rowDescriptor.value displayText];
|
||||
return self.rowDescriptor.displayTextValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
@interface XLFormOptionsObject : NSObject <XLFormOptionObject,NSCoding>
|
||||
|
||||
@property (nonatomic) NSString * formDisplaytext;
|
||||
@property (nonatomic) id formValue;
|
||||
|
||||
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText;
|
||||
+(XLFormOptionsObject *)formOptionsOptionForValue:(id)value fromOptions:(NSArray *)options;
|
||||
+(XLFormOptionsObject *)formOptionsOptionForDisplayText:(NSString *)displayText fromOptions:(NSArray *)options;
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
#import "XLFormOptionsObject.h"
|
||||
|
||||
@implementation XLFormOptionsObject
|
||||
{
|
||||
NSString * _formDisplaytext;
|
||||
id _formValue;
|
||||
}
|
||||
|
||||
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText
|
||||
{
|
||||
@@ -85,6 +81,7 @@
|
||||
{
|
||||
return _formValue;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
-(void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
@@ -94,6 +91,7 @@
|
||||
[encoder encodeObject:self.formDisplayText
|
||||
forKey:@"formDisplayText"];
|
||||
}
|
||||
|
||||
-(instancetype)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self=[super init])) {
|
||||
@@ -108,4 +106,5 @@
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -52,6 +52,7 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) {
|
||||
-(XLFormBaseCell *)updateFormRow:(XLFormRowDescriptor *)formRow;
|
||||
|
||||
-(NSDictionary *)formValues;
|
||||
-(NSDictionary *)formValuesIncludingHidden;
|
||||
-(NSDictionary *)httpParameters;
|
||||
|
||||
-(XLFormRowDescriptor *)formRowFormMultivaluedFormSection:(XLFormSectionDescriptor *)formSection;
|
||||
@@ -60,6 +61,7 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) {
|
||||
|
||||
-(NSArray *)formValidationErrors;
|
||||
-(void)showFormValidationError:(NSError *)error;
|
||||
-(void)showFormValidationError:(NSError *)error withTitle:(NSString*)title;
|
||||
|
||||
-(UITableViewRowAnimation)insertRowAnimationForRow:(XLFormRowDescriptor *)formRow;
|
||||
-(UITableViewRowAnimation)deleteRowAnimationForRow:(XLFormRowDescriptor *)formRow;
|
||||
|
||||
@@ -346,6 +346,11 @@
|
||||
return [self.form formValues];
|
||||
}
|
||||
|
||||
-(NSDictionary *)formValuesIncludingHidden
|
||||
{
|
||||
return [self.form formValuesIncludingHidden];
|
||||
}
|
||||
|
||||
-(NSDictionary *)httpParameters
|
||||
{
|
||||
return [self.form httpParameters:self];
|
||||
@@ -492,6 +497,38 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
-(void)showFormValidationError:(NSError *)error withTitle:(NSString*)title
|
||||
{
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
|
||||
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(title, nil)
|
||||
message:error.localizedDescription
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"OK", nil)
|
||||
otherButtonTitles:nil];
|
||||
[alertView show];
|
||||
#else
|
||||
if ([UIAlertController class]){
|
||||
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(title, nil)
|
||||
message:error.localizedDescription
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:nil]];
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
#ifndef XL_APP_EXTENSIONS
|
||||
else{
|
||||
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(title, nil)
|
||||
message:error.localizedDescription
|
||||
delegate:self
|
||||
cancelButtonTitle:NSLocalizedString(@"OK", nil)
|
||||
otherButtonTitles:nil];
|
||||
[alertView show];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
-(void)performFormSelector:(SEL)selector withObject:(id)sender
|
||||
{
|
||||
UIResponder * responder = [self targetForAction:selector withSender:sender];;
|
||||
|
||||
@@ -82,6 +82,7 @@ typedef NS_OPTIONS(NSUInteger, XLFormRowNavigationOptions) {
|
||||
-(nullable NSIndexPath *)indexPathOfFormRow:(nonnull XLFormRowDescriptor *)formRow;
|
||||
|
||||
-(nonnull NSDictionary *)formValues;
|
||||
-(nonnull NSDictionary *)formValuesIncludingHidden;
|
||||
-(nonnull NSDictionary *)httpParameters:(nonnull XLFormViewController *)formViewController;
|
||||
|
||||
-(nonnull NSArray *)localValidationErrors:(nonnull XLFormViewController *)formViewController;
|
||||
|
||||
@@ -284,13 +284,25 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(NSDictionary *)formValuesIncludingHidden
|
||||
{
|
||||
return [self formValuesWithHidden:YES];
|
||||
}
|
||||
|
||||
-(NSDictionary *)formValues
|
||||
{
|
||||
NSMutableDictionary * result = [NSMutableDictionary dictionary];
|
||||
for (XLFormSectionDescriptor * section in self.formSections) {
|
||||
return [self formValuesWithHidden:NO];
|
||||
}
|
||||
|
||||
-(NSDictionary *)formValuesWithHidden:(BOOL)includeHidden
|
||||
{
|
||||
NSArray* sections = includeHidden ? self.allSections : self.formSections;
|
||||
NSMutableDictionary* result = [NSMutableDictionary dictionary];
|
||||
for (XLFormSectionDescriptor * section in sections) {
|
||||
NSArray* rows = includeHidden ? section.allRows : section.formRows;
|
||||
if (section.multivaluedTag.length > 0){
|
||||
NSMutableArray * multiValuedValuesArray = [NSMutableArray new];
|
||||
for (XLFormRowDescriptor * row in section.formRows) {
|
||||
NSMutableArray* multiValuedValuesArray = [NSMutableArray new];
|
||||
for (XLFormRowDescriptor * row in rows) {
|
||||
if (row.value){
|
||||
[multiValuedValuesArray addObject:row.value];
|
||||
}
|
||||
@@ -298,7 +310,7 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
|
||||
[result setObject:multiValuedValuesArray forKey:section.multivaluedTag];
|
||||
}
|
||||
else{
|
||||
for (XLFormRowDescriptor * row in section.formRows) {
|
||||
for (XLFormRowDescriptor * row in rows) {
|
||||
if (row.tag.length > 0){
|
||||
[result setObject:(row.value ?: [NSNull null]) forKey:row.tag];
|
||||
}
|
||||
|
||||
@@ -69,5 +69,6 @@ typedef NS_ENUM(NSUInteger, XLFormSectionInsertMode) {
|
||||
-(void)addFormRow:(nonnull XLFormRowDescriptor *)formRow beforeRow:(nonnull XLFormRowDescriptor *)beforeRow;
|
||||
-(void)removeFormRowAtIndex:(NSUInteger)index;
|
||||
-(void)removeFormRow:(nonnull XLFormRowDescriptor *)formRow;
|
||||
-(void)moveRowAtIndexPath:(nonnull NSIndexPath *)sourceIndex toIndexPath:(nonnull NSIndexPath *)destinationIndex;
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user