36 Commits

Author SHA1 Message Date
Mathias Claassen c7d5708f16 update pod version 2016-06-16 10:34:54 -03:00
Mathias Claassen dd294cc709 Merge pull request #804 from xmartlabs/fix/multiEmpty
added count to empty check. Helpful to validate multiple selectors be…
2016-06-13 17:24:08 -03:00
Mathias Claassen cda0327def added count to empty check. Helpful to validate multiple selectors being empty 2016-06-13 17:23:44 -03:00
Mathias Claassen 9a2bdf1ca0 Merge pull request #797 from xmartlabs/fix/decimals
Fix decimal number formatting. closes #514
2016-06-02 13:46:49 -03:00
Mathias Claassen d8b67b5c21 Fix decimal number formatting. closes #514 2016-06-02 13:46:25 -03:00
Mathias Claassen f30fa9bb31 Merge pull request #796 from xmartlabs/feature/cellHeight
Added height property to XLFormRowDescriptor
2016-06-02 12:52:47 -03:00
Mathias Claassen 9b1e7d6d4e Added height property to XLFormRowDescriptor 2016-06-02 12:41:12 -03:00
Mathias Claassen fac9cefc2b Merge pull request #652 from droidlabs/custom-multiselect
Row with multiple selector should support custom controller
2016-06-02 11:14:23 -03:00
Mathias Claassen d202a40824 Merge pull request #794 from xmartlabs/readmeUpdate
updated readme with some comments. Fixes #771, fixes #727, fixes #696
2016-06-01 15:16:15 -03:00
Mathias Claassen d185e642e0 updated readme with some comments. Fixes #771, fixes #727, fixes #696 2016-06-01 15:15:35 -03:00
Mathias Claassen 743c5d289a Merge pull request #695 from realestate-com-au/hotfix/code-sign
Changed Release config to use iPhone Distribution code sign identity
2016-06-01 14:20:54 -03:00
Mathias Claassen de86c5e60e Merge pull request #306 from ziogaschr/add-support-NSFormatter
Add support for NSFormatter.
 closes #77 , closes #195 , closes #176 closes #64
2016-05-31 12:15:00 -03:00
Chris Ziogas f52c532fec Add support for NSFormatter 2016-05-31 17:57:18 +03:00
Mathias Claassen 274892dc95 Merge pull request #792 from xmartlabs/fix/validation
Do validation can be nullable. fixes #705
2016-05-31 11:54:29 -03:00
Mathias Claassen 09b28286de Do validation can be nullable. fixes #705 2016-05-31 11:54:06 -03:00
Mathias Claassen bbca57a2e6 Merge pull request #456 from conradwt/master
Update project README
2016-05-31 11:34:35 -03:00
Mathias Claassen d29275b780 Merge pull request #523 from MuscleRumble/appextensions
Fixed #357 by adding XL_APP_EXTENSIONS macro so that XLForm can be used in App Extensions
2016-05-31 11:30:01 -03:00
Mathias Claassen 11f54cee17 Merge pull request #686 from alejandrogarin/numberFormatter
Controlling formatting output when the rowType is XLFormRowDescriptorTypeNumber or XLFormRowDescriptorTypeDecimal
2016-05-31 11:16:24 -03:00
Mathias Claassen 418b3e4c96 Merge pull request #782 from kiancheong/UITextView-ShouldChange-Delegate
Added shouldChangeTextInRange delegate call for UITextView.
2016-05-31 11:03:13 -03:00
Mathias Claassen 6da2fc456c Merge pull request #791 from xmartlabs/fix/value2CellStyle
fix crash when using cell style Value2. closes #770
2016-05-30 17:25:09 -03:00
Mathias Claassen 52be3f3531 fix crash when using cell style Value2. closes #770 2016-05-30 17:14:13 -03:00
Mathias Claassen 5e00deb474 Merge pull request #790 from xmartlabs/fix/textFieldPercentage
Fix when the textFieldPercentage is applied. Closes #776
2016-05-30 16:46:37 -03:00
Mathias Claassen 2a8ebf2af5 Fix when the textFieldPercentage is applied. Closes #776 2016-05-30 16:46:09 -03:00
Mathias Claassen 5c716a665d Merge pull request #789 from mbjacks/master
fix crash when adding a validator to a copied row descriptor
2016-05-30 16:21:51 -03:00
Matt Jackson 60e67b9651 fix crash when adding a validator to a copied row descriptor 2016-05-27 14:20:56 -07:00
Mathias Claassen 6aac513398 Merge pull request #753 from jpmhouston/example-podfile
updated example podfile for cocoapods 1.0 compatibility
2016-05-24 16:58:11 -03:00
Mathias Claassen 0491752090 update pod spec for new release 2016-05-24 16:56:15 -03:00
kiancheong 51760a535a Added shouldChangeTextInRange delegate call for UITextView. 2016-05-11 11:13:17 +08:00
Pierre Houston 0d24f47f75 updated podfile for compatibility with cocoapods 1.0, did pod deintegrate on project to remove cruft
- fixes warnings on 'pod install': 'The dependency ... is not used in any concrete target'
2016-03-22 18:33:01 -07:00
Tobias Hagemann 756fdb914b Merge branch 'master' of https://github.com/xmartlabs/XLForm into appextensions 2016-01-16 11:29:29 +01:00
Iskander Haziev 3df413b0fa Row with multiple selector should support custom controller 2016-01-05 17:18:40 +03:00
Stephen Yao 97b79f1f93 Changed Release config to distribution profile for code signing
(cherry picked from commit c4d7f7c9ef5a3a5d6799a8ff6e6a34872ea4b7bd)
2016-01-04 14:35:35 +11:00
Alejandro Garin ba949c3697 check if self conform to protocol XLFormOptionObject before checking if the object is kind of class NSString or NSNumber. This allow better control in the formatted output if the object is a NSNumber 2015-12-28 15:00:44 -03:00
Tobias Hagemann e31c6db521 Merge branch 'master' of https://github.com/xmartlabs/XLForm into appextensions 2015-09-18 17:49:06 +02:00
Tobias Hagemann 15a4ce9d83 Fixed #357 by adding XL_APP_EXTENSIONS macro so that XLForm can be used in App Extensions 2015-08-25 16:41:56 +02:00
Conrad Taylor 5b136eb458 Enhance the copy for creating a form and add a section for Storyboard users. 2015-07-23 13:19:54 -07:00
19 changed files with 636 additions and 140 deletions
+6
View File
@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
### Latest:
* Added XL_APP_EXTENSIONS macro to allow app extensions (@MuscleRumble #357)
* Added shouldChangeTextInRange delegate call for UITextView. (@kiancheong #782)
* Added support for NSFormatter (@ziogaschr, @fwhenin, @bhirt-bpl #306)
* Added `height` property to XLFormRowDescriptor to allow setting height of individual cells.
### Version 3.1.2:
* Update row in `cellForRowAtIndexPath` instead of `willDisplayCell`
* Added cancel action to image selector (by koenpunt)
* Other minor fixes
@@ -34,6 +34,7 @@
#import "CustomRowsViewController.h"
#import "AccessoryViewFormViewController.h"
#import "PredicateFormViewController.h"
#import "FormattersViewController.h"
NSString * const kTextFieldAndTextView = @"TextFieldAndTextView";
NSString * const kSelectors = @"Selectors";
@@ -46,6 +47,7 @@ NSString * const kMultivaluedOnlyReorder = @"MultivaluedOnlyReorder";
NSString * const kMultivaluedOnlyInsert = @"MultivaluedOnlyInsert";
NSString * const kMultivaluedOnlyDelete = @"MultivaluedOnlyDelete";
NSString * const kValidations= @"Validations";
NSString * const kFormatters = @"Formatters";
@interface ExamplesFormViewController ()
@@ -113,6 +115,11 @@ NSString * const kValidations= @"Validations";
row.action.viewControllerClass = [DatesFormViewController class];
[section addFormRow:row];
// NSFormatters
row = [XLFormRowDescriptor formRowDescriptorWithTag:kFormatters rowType:XLFormRowDescriptorTypeButton title:@"NSFormatter Support"];
row.action.viewControllerClass = [FormattersViewController class];
[section addFormRow:row];
// Others
row = [XLFormRowDescriptor formRowDescriptorWithTag:kOthes rowType:XLFormRowDescriptorTypeButton title:@"Other Rows"];
row.action.formSegueIdentifier = @"OthersFormViewControllerSegue";
@@ -0,0 +1,13 @@
//
// FormattersViewController.h
// XLForm
//
// Created by Freddy Henin on 12/29/14.
// Copyright (c) 2014 Xmartlabs. All rights reserved.
//
#import "XLFormViewController.h"
@interface FormattersViewController : XLFormViewController
@end
@@ -0,0 +1,115 @@
//
// FormattersViewController.m
// XLForm
//
// Created by Freddy Henin on 12/29/14.
// Copyright (c) 2014 Xmartlabs. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "XLForm.h"
#import "FormattersViewController.h"
#import <SHSPhoneComponent/SHSPhoneNumberFormatter+UserConfig.h>
// Simple little class to demonstraite currency formatting. Unfortunally we have to subclass
// NSNumberFormatter to work aroundn some long known rounding bugs with NSNumberFormatter
// http://stackoverflow.com/questions/12580162/nsstring-to-nsdate-conversion-issue
@interface CurrencyFormatter : NSNumberFormatter
@property (readonly) NSDecimalNumberHandler *roundingBehavior;
@end
@implementation CurrencyFormatter
- (id) init
{
self = [super init];
if (self) {
[self setNumberStyle: NSNumberFormatterCurrencyStyle];
[self setGeneratesDecimalNumbers:YES];
NSUInteger currencyScale = [self maximumFractionDigits];
_roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:currencyScale raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE];
}
return self;
}
//- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error
//{
// NSDecimalNumber *number;
// BOOL success = [super getObjectValue:&number forString:string errorDescription:error];
//
// if (success) {
// *anObject = [number decimalNumberByRoundingAccordingToBehavior:_roundingBehavior];
// }
// else {
// *anObject = nil;
// }
//
// return success;
//}
@end
@interface FormattersViewController ()
@end
@implementation FormattersViewController
-(id)init
{
XLFormDescriptor * formDescriptor = [XLFormDescriptor formDescriptorWithTitle:@"Text Fields"];
XLFormSectionDescriptor * section;
XLFormRowDescriptor * row;
formDescriptor.assignFirstResponderOnShow = NO;
section = [XLFormSectionDescriptor formSection];
section.title = @"NSFormatter Support";
section.footerTitle = @"Rows can be configured to use the formatter as you type or to toggle on and off during for display/editing. You will most likely need custom NSFormatter objects to do on the fly formatting since NSNumberFormatter is pretty limited in this regard.";
[formDescriptor addFormSection:section];
// Phone
SHSPhoneNumberFormatter *formatter = [[SHSPhoneNumberFormatter alloc] init];
[formatter setDefaultOutputPattern:@"(###) ###-####" imagePath:nil];
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"phone" rowType:XLFormRowDescriptorTypePhone title:@"US Phone"];
row.valueFormatter = formatter;
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
row.useValueFormatterDuringInput = YES;
[section addFormRow:row];
// Currency
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"currency" rowType:XLFormRowDescriptorTypeDecimal title:@"USD"];
CurrencyFormatter *numberFormatter = [[CurrencyFormatter alloc] init];
row.valueFormatter = numberFormatter;
row.value = [NSDecimalNumber numberWithDouble:9.95];
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
[section addFormRow:row];
// Accounting
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"percent" rowType:XLFormRowDescriptorTypeNumber title:@"Test Score"];
NSNumberFormatter *acctFormatter = [[NSNumberFormatter alloc] init];
[acctFormatter setNumberStyle:NSNumberFormatterPercentStyle];
row.valueFormatter = acctFormatter;
row.value = @(0.75);
[row.cellConfigAtConfigure setObject:@(NSTextAlignmentRight) forKey:@"textField.textAlignment"];
[section addFormRow:row];
section = [XLFormSectionDescriptor formSection];
[formDescriptor addFormSection:section];
return [super initWithForm:formDescriptor];
}
@end
+4
View File
@@ -1,6 +1,8 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target 'XLForm' do
pod 'XLForm', :path => '../../'
#Following pods are used for custom row examples
@@ -8,3 +10,5 @@ pod 'AFNetworking', '~> 2.0', :inhibit_warnings => true
pod 'XLData', :git => 'https://github.com/xmartlabs/XLData.git', :commit => '1f9019b56242a2019c7f7e11ec4ef823c397ebcf', :inhibit_warnings => true
pod 'JVFloatLabeledTextField', '1.0.2', :inhibit_warnings => true
pod 'AXRatingView', '1.0.3', :inhibit_warnings => true
pod 'SHSPhoneComponent'
end
+78
View File
@@ -0,0 +1,78 @@
PODS:
- AFNetworking (2.6.3):
- AFNetworking/NSURLConnection (= 2.6.3)
- AFNetworking/NSURLSession (= 2.6.3)
- AFNetworking/Reachability (= 2.6.3)
- AFNetworking/Security (= 2.6.3)
- AFNetworking/Serialization (= 2.6.3)
- AFNetworking/UIKit (= 2.6.3)
- AFNetworking/NSURLConnection (2.6.3):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/NSURLSession (2.6.3):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (2.6.3)
- AFNetworking/Security (2.6.3)
- AFNetworking/Serialization (2.6.3)
- AFNetworking/UIKit (2.6.3):
- AFNetworking/NSURLConnection
- AFNetworking/NSURLSession
- AXRatingView (1.0.3)
- JVFloatLabeledTextField (1.0.2)
- SHSPhoneComponent (2.15)
- XLData (2.0.0):
- XLData/Core (= 2.0.0)
- XLData/CoreData (= 2.0.0)
- XLData/CoreRemote (= 2.0.0)
- XLData/DataStore (= 2.0.0)
- XLData/RemoteCoreData (= 2.0.0)
- XLData/RemoteDataStore (= 2.0.0)
- XLData/Core (2.0.0)
- XLData/CoreData (2.0.0):
- XLData/Core
- XLData/CoreRemote (2.0.0):
- AFNetworking (~> 2.0)
- XLData/DataStore (2.0.0):
- XLData/Core
- XLData/RemoteCoreData (2.0.0):
- XLData/CoreData
- XLData/CoreRemote
- XLData/RemoteDataStore (2.0.0):
- XLData/CoreRemote
- XLData/DataStore
- XLForm (3.1.2)
DEPENDENCIES:
- AFNetworking (~> 2.0)
- AXRatingView (= 1.0.3)
- JVFloatLabeledTextField (= 1.0.2)
- SHSPhoneComponent
- XLData (from `https://github.com/xmartlabs/XLData.git`, commit `1f9019b56242a2019c7f7e11ec4ef823c397ebcf`)
- XLForm (from `../../`)
EXTERNAL SOURCES:
XLData:
:commit: 1f9019b56242a2019c7f7e11ec4ef823c397ebcf
:git: https://github.com/xmartlabs/XLData.git
XLForm:
:path: ../../
CHECKOUT OPTIONS:
XLData:
:commit: 1f9019b56242a2019c7f7e11ec4ef823c397ebcf
:git: https://github.com/xmartlabs/XLData.git
SPEC CHECKSUMS:
AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60
AXRatingView: ccaadc1bbda99a4b7e1d556059482d2b933a9f4e
JVFloatLabeledTextField: 58a3a32cfb800e5b224f676987e7c13abf50a14d
SHSPhoneComponent: 4cec0653a150ad63cbc52b0c8b29ce2d3c9c26f0
XLData: df725c6179e2e0c80bf56a1ecad9afd169707a6d
XLForm: 6bb3c20857e2983cf494cb8b4d666c2a24673d5e
PODFILE CHECKSUM: 80615792e859be64c95add3bb57c1596234faf95
COCOAPODS: 1.0.0
@@ -33,7 +33,6 @@
28A85D5918E346C100E81A26 /* XLFormImageSelectorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 28A85D5818E346C100E81A26 /* XLFormImageSelectorCell.m */; };
28DBB04118D76FDC00FB8A8B /* MultivaluedFormViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28DBB04018D76FDC00FB8A8B /* MultivaluedFormViewController.m */; };
28F89F2E1AA4EA5600E90218 /* ValidationExamplesFormViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F89F2D1AA4EA5600E90218 /* ValidationExamplesFormViewController.m */; };
2CA9A3FC06E94345A2FDE415 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F6DF43B7BBF44F72A4493E8E /* libPods.a */; };
3C0357F01AB0D82300200C8A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3C0357EF1AB0D82300200C8A /* Images.xcassets */; };
3C3B01D51AB741EF0027CD45 /* XLFormRatingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B01D31AB741EF0027CD45 /* XLFormRatingCell.m */; };
3C3B01DA1AB7497D0027CD45 /* XLFormWeekDaysCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B01D81AB7497D0027CD45 /* XLFormWeekDaysCell.m */; };
@@ -41,6 +40,7 @@
3C3B01E21AB7499A0027CD45 /* XLRatingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B01E01AB7499A0027CD45 /* XLRatingView.m */; };
3C3B01F01AB74BDC0027CD45 /* FloatLabeledTextFieldCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B01EF1AB74BDC0027CD45 /* FloatLabeledTextFieldCell.m */; };
3CDAFC7A1AB0AFA4000F75B6 /* CustomRowsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3CDAFC791AB0AFA4000F75B6 /* CustomRowsViewController.m */; };
5BB6B032D80344C9E7D956CD /* libPods-XLForm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19383D268EF8024CB33FCCA4 /* libPods-XLForm.a */; };
66B6266E1AE0055100007886 /* DateAndTimeValueTrasformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 66B6266D1AE0055100007886 /* DateAndTimeValueTrasformer.m */; };
BF01E9281C21F0BB00BDE045 /* XLFormInlineSegmentedCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BF01E9271C21F0BB00BDE045 /* XLFormInlineSegmentedCell.m */; };
BF9DB1D51AE0436600B985E7 /* BlogExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF9DB1D21AE0436600B985E7 /* BlogExampleViewController.m */; };
@@ -49,9 +49,11 @@
BFE91AFB1AE159B200DE5231 /* BasicPredicateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BFE91AFA1AE159B200DE5231 /* BasicPredicateViewController.m */; };
D51B8B2C19126664008C0478 /* XLFormCustomCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D51B8B2B19126664008C0478 /* XLFormCustomCell.m */; };
DEA6EF911B57D6CC000F4893 /* HTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DEA6EF901B57D6CC000F4893 /* HTTPSessionManager.m */; };
DEB8235C1AD5529A00AF9FE2 /* FormattersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DEB8235B1AD5529A00AF9FE2 /* FormattersViewController.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
19383D268EF8024CB33FCCA4 /* libPods-XLForm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-XLForm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
281E5BE719538F4A006D93C5 /* CLLocationValueTrasformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CLLocationValueTrasformer.h; path = Examples/Selectors/CustomSelectors/XLFormRowViewController/CLLocationValueTrasformer.h; sourceTree = "<group>"; };
281E5BE819538F4A006D93C5 /* CLLocationValueTrasformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CLLocationValueTrasformer.m; path = Examples/Selectors/CustomSelectors/XLFormRowViewController/CLLocationValueTrasformer.m; sourceTree = "<group>"; };
282EB27A1AB5FF33004A736F /* AccessoryViewFormViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AccessoryViewFormViewController.h; path = Examples/AccessoryViews/AccessoryViewFormViewController.h; sourceTree = "<group>"; };
@@ -111,10 +113,10 @@
3C3B01EF1AB74BDC0027CD45 /* FloatLabeledTextFieldCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FloatLabeledTextFieldCell.m; path = Examples/CustomRows/FloatLabeledTextField/FloatLabeledTextFieldCell.m; sourceTree = "<group>"; };
3CDAFC781AB0AFA4000F75B6 /* CustomRowsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomRowsViewController.h; path = Examples/CustomRows/CustomRowsViewController.h; sourceTree = "<group>"; };
3CDAFC791AB0AFA4000F75B6 /* CustomRowsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CustomRowsViewController.m; path = Examples/CustomRows/CustomRowsViewController.m; sourceTree = "<group>"; };
5F6FC67A75254B60005DC716 /* Pods-XLForm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm.debug.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm/Pods-XLForm.debug.xcconfig"; sourceTree = "<group>"; };
66B6266C1AE0055100007886 /* DateAndTimeValueTrasformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DateAndTimeValueTrasformer.h; path = Examples/Dates/DateAndTimeValueTrasformer.h; sourceTree = "<group>"; };
66B6266D1AE0055100007886 /* DateAndTimeValueTrasformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DateAndTimeValueTrasformer.m; path = Examples/Dates/DateAndTimeValueTrasformer.m; sourceTree = "<group>"; };
7B0D2D6A86E2A41ED22E8A35 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
976A33EE62A018A7257B4878 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
B98C1213E7C714A861219C81 /* Pods-XLForm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm.release.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm/Pods-XLForm.release.xcconfig"; sourceTree = "<group>"; };
BF01E9261C21F0BB00BDE045 /* XLFormInlineSegmentedCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XLFormInlineSegmentedCell.h; path = "Inline Segmented/XLFormInlineSegmentedCell.h"; sourceTree = "<group>"; };
BF01E9271C21F0BB00BDE045 /* XLFormInlineSegmentedCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLFormInlineSegmentedCell.m; path = "Inline Segmented/XLFormInlineSegmentedCell.m"; sourceTree = "<group>"; };
BF9DB1D11AE0436600B985E7 /* BlogExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogExampleViewController.h; path = Examples/PredicateExamples/BlogExampleViewController.h; sourceTree = SOURCE_ROOT; };
@@ -127,7 +129,8 @@
D51B8B2B19126664008C0478 /* XLFormCustomCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLFormCustomCell.m; path = Examples/Others/CustomCells/XLFormCustomCell.m; sourceTree = "<group>"; };
DEA6EF8F1B57D6CC000F4893 /* HTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSessionManager.h; path = Examples/Selectors/HTTPSessionManager.h; sourceTree = "<group>"; };
DEA6EF901B57D6CC000F4893 /* HTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPSessionManager.m; path = Examples/Selectors/HTTPSessionManager.m; sourceTree = "<group>"; };
F6DF43B7BBF44F72A4493E8E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
DEB8235A1AD5529A00AF9FE2 /* FormattersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormattersViewController.h; sourceTree = "<group>"; };
DEB8235B1AD5529A00AF9FE2 /* FormattersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FormattersViewController.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -139,22 +142,13 @@
2850C5FE18D0F706002B7D0A /* CoreGraphics.framework in Frameworks */,
2850C60018D0F706002B7D0A /* UIKit.framework in Frameworks */,
2850C5FC18D0F706002B7D0A /* Foundation.framework in Frameworks */,
2CA9A3FC06E94345A2FDE415 /* libPods.a in Frameworks */,
5BB6B032D80344C9E7D956CD /* libPods-XLForm.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
15E61D225B0D27FAB51BDD90 /* Pods */ = {
isa = PBXGroup;
children = (
7B0D2D6A86E2A41ED22E8A35 /* Pods.debug.xcconfig */,
976A33EE62A018A7257B4878 /* Pods.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
282C5EEF18D33C1800A5D47C /* Inputs */ = {
isa = PBXGroup;
children = (
@@ -261,7 +255,7 @@
2850C60118D0F706002B7D0A /* XLForm */,
2850C5FA18D0F706002B7D0A /* Frameworks */,
2850C5F918D0F706002B7D0A /* Products */,
15E61D225B0D27FAB51BDD90 /* Pods */,
B6478577DDCB0DDDD433C572 /* Pods */,
);
sourceTree = "<group>";
};
@@ -280,7 +274,7 @@
2850C5FB18D0F706002B7D0A /* Foundation.framework */,
2850C5FD18D0F706002B7D0A /* CoreGraphics.framework */,
2850C5FF18D0F706002B7D0A /* UIKit.framework */,
F6DF43B7BBF44F72A4493E8E /* libPods.a */,
19383D268EF8024CB33FCCA4 /* libPods-XLForm.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -312,6 +306,7 @@
282EB2791AB5FD66004A736F /* AccessoryViews */,
3CDAFC741AB0AEE5000F75B6 /* CustomRows */,
28F89F2B1AA4E99500E90218 /* Validations */,
DEB823591AD5529A00AF9FE2 /* Formatters */,
283C6B7A1999BA1B00A5283D /* UICustomization */,
28A76624193251E500D69546 /* AppDelegate.m */,
28A8083C190D903D009D77F8 /* StoryboardExample */,
@@ -429,6 +424,15 @@
name = CustomRows;
sourceTree = "<group>";
};
B6478577DDCB0DDDD433C572 /* Pods */ = {
isa = PBXGroup;
children = (
5F6FC67A75254B60005DC716 /* Pods-XLForm.debug.xcconfig */,
B98C1213E7C714A861219C81 /* Pods-XLForm.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
BF01E9251C21F02D00BDE045 /* Inline Segmented */ = {
isa = PBXGroup;
children = (
@@ -461,6 +465,16 @@
name = SessionManager;
sourceTree = "<group>";
};
DEB823591AD5529A00AF9FE2 /* Formatters */ = {
isa = PBXGroup;
children = (
DEB8235A1AD5529A00AF9FE2 /* FormattersViewController.h */,
DEB8235B1AD5529A00AF9FE2 /* FormattersViewController.m */,
);
name = Formatters;
path = Examples/Formatters;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -468,12 +482,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 2850C62418D0F707002B7D0A /* Build configuration list for PBXNativeTarget "XLForm" */;
buildPhases = (
0EA9FCE3DA0D444498836D37 /* Check Pods Manifest.lock */,
EBE0335CCC7588D83B89A92A /* 📦 Check Pods Manifest.lock */,
2850C5F418D0F706002B7D0A /* Sources */,
2850C5F518D0F706002B7D0A /* Frameworks */,
2850C5F618D0F706002B7D0A /* Resources */,
CFE72E068B5F4D9BB45FB757 /* Copy Pods Resources */,
734CC62A7A974D37CC982576 /* Embed Pods Frameworks */,
32EB30E0A90A4E91864B1D3C /* 📦 Embed Pods Frameworks */,
DE3D12F5596780A66C6C3D4A /* 📦 Copy Pods Resources */,
);
buildRules = (
);
@@ -528,14 +542,44 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0EA9FCE3DA0D444498836D37 /* Check Pods Manifest.lock */ = {
32EB30E0A90A4E91864B1D3C /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
DE3D12F5596780A66C6C3D4A /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
EBE0335CCC7588D83B89A92A /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -543,36 +587,6 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
734CC62A7A974D37CC982576 /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
CFE72E068B5F4D9BB45FB757 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -606,6 +620,7 @@
BF01E9281C21F0BB00BDE045 /* XLFormInlineSegmentedCell.m in Sources */,
BF9DB1D61AE0436600B985E7 /* PredicateFormViewController.m in Sources */,
BFE91AFB1AE159B200DE5231 /* BasicPredicateViewController.m in Sources */,
DEB8235C1AD5529A00AF9FE2 /* FormattersViewController.m in Sources */,
2843EB5218D4CFC700F13E2B /* OthersFormViewController.m in Sources */,
2843EB4B18D496F600F13E2B /* SelectorsFormViewController.m in Sources */,
28468EA418EF41D300DBB015 /* InputsFormViewController.m in Sources */,
@@ -708,7 +723,7 @@
};
2850C62518D0F707002B7D0A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7B0D2D6A86E2A41ED22E8A35 /* Pods.debug.xcconfig */;
baseConfigurationReference = 5F6FC67A75254B60005DC716 /* Pods-XLForm.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -725,10 +740,11 @@
};
2850C62618D0F707002B7D0A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 976A33EE62A018A7257B4878 /* Pods.release.xcconfig */;
baseConfigurationReference = B98C1213E7C714A861219C81 /* Pods-XLForm.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "XLForm/XLForm-Prefix.pch";
INFOPLIST_FILE = "XLForm/XLForm-Info.plist";
@@ -356,11 +356,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 2847A6BD1AAF2679000A2ABE /* Build configuration list for PBXNativeTarget "SwiftExample" */;
buildPhases = (
21FCE00817B1AE1029F382A4 /* Check Pods Manifest.lock */,
21FCE00817B1AE1029F382A4 /* 📦 Check Pods Manifest.lock */,
2847A69A1AAF2679000A2ABE /* Sources */,
2847A69B1AAF2679000A2ABE /* Frameworks */,
2847A69C1AAF2679000A2ABE /* Resources */,
A0F2DA95250A4C3E69515D96 /* Copy Pods Resources */,
A0F2DA95250A4C3E69515D96 /* 📦 Copy Pods Resources */,
DCA1F7B1D7E04613B3E151C1 /* 📦 Embed Pods Frameworks */,
);
buildRules = (
);
@@ -421,14 +422,14 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
21FCE00817B1AE1029F382A4 /* Check Pods Manifest.lock */ = {
21FCE00817B1AE1029F382A4 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Check Pods Manifest.lock";
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -436,14 +437,14 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
A0F2DA95250A4C3E69515D96 /* Copy Pods Resources */ = {
A0F2DA95250A4C3E69515D96 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Copy Pods Resources";
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -451,6 +452,21 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample-resources.sh\"\n";
showEnvVarsInLog = 0;
};
DCA1F7B1D7E04613B3E151C1 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+143 -42
View File
@@ -38,8 +38,75 @@ What XLForm does
How to create a form
-----------------------------
## How to create a form
#### Create an instance of XLFormViewController
##### Swift
```swift
class CalendarEventFormViewController : XLFormViewController {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
func initializeForm() {
// Implementation details covered in the next section.
}
}
```
##### Objective-C
```objc
#import "XLFormViewController.h"
@interface CalendarEventFormViewController: XLFormViewController
@end
```
```objc
@interface ExamplesFormViewController ()
@end
@implementation ExamplesFormViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self){
[self initializeForm];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self){
[self initializeForm];
}
return self;
}
- (void)initializeForm {
// Implementation details covered in the next section.
}
@end
```
##### Implementing the initializeForm method
To create a form we should declare it through a `XLFormDescriptor` instance and assign it to a `XLFormViewController` instance. As we said XLForm works based on a DSL that hides complex and boilerplate stuff without losing the power and flexibility of hand-made forms.
@@ -51,50 +118,56 @@ To define a form we use 3 classes:
A form definition is a `XLFormDescriptor` instance that contains one or more sections (`XLFormSectionDescriptor` instances) and each section contains several rows (`XLFormRowDescriptor` instance). As you may have noticed the DSL structure is analog to the structure of a `UITableView` (Table -->> Sections -- >> Rows). The resulting table-view form's structure (sections and rows order) mirrors the definition's structure.
#####Let's see part of the iOS Calendar Event Form definition.
##### Let's see an example implementation of initializeForm to define the iOS Calendar Event Form
```objc
XLFormDescriptor * form;
XLFormSectionDescriptor * section;
XLFormRowDescriptor * row;
- (void)initializeForm {
XLFormDescriptor * form;
XLFormSectionDescriptor * section;
XLFormRowDescriptor * row;
form = [XLFormDescriptor formDescriptorWithTitle:@"Add Event"];
form = [XLFormDescriptor formDescriptorWithTitle:@"Add Event"];
// First section
section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
// First section
section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
// Title
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"title" rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:@"Title" forKey:@"textField.placeholder"];
[section addFormRow:row];
// Title
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"title" rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:@"Title" forKey:@"textField.placeholder"];
[section addFormRow:row];
// Location
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"location" rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:@"Location" forKey:@"textField.placeholder"];
[section addFormRow:row];
// Location
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"location" rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:@"Location" forKey:@"textField.placeholder"];
[section addFormRow:row];
// Second Section
section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
// Second Section
section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
// All-day
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"all-day" rowType:XLFormRowDescriptorTypeBooleanSwitch title:@"All-day"];
[section addFormRow:row];
// All-day
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"all-day" rowType:XLFormRowDescriptorTypeBooleanSwitch title:@"All-day"];
[section addFormRow:row];
// Starts
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"starts" rowType:XLFormRowDescriptorTypeDateTimeInline title:@"Starts"];
row.value = [NSDate dateWithTimeIntervalSinceNow:60*60*24];
[section addFormRow:row];
// Starts
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"starts" rowType:XLFormRowDescriptorTypeDateTimeInline title:@"Starts"];
row.value = [NSDate dateWithTimeIntervalSinceNow:60*60*24];
[section addFormRow:row];
}
```
XLForm will load the table-view form from the previously explained definition. The most interesting part is that it will update the table-view form based on the form definition modifications.
That means that we are able to make changes on the table-view form adding or removing section definitions or row definitions to the form definition on runtime and you will never need to care again about `NSIndexPath`, `UITableViewDelegate`, `UITableViewDataSource` or other complexities.
**To see more complex form definitions take a look at the example application in the Examples folder of this repository. You can also run the examples on your own device if you wish.** XLForm **has no** dependencies over other pods, anyway the examples project makes use of some cocoapods to show advanced XLForm features.
## Using XLForm with Storyboards
* Perform the steps from **How to create a form**
* In Interface Builder (IB), drag-and-drop a **UIViewController** onto the Storyboard
* Associate your custom form class to the **UIViewController** using the **Identity Inspector**
How to run XLForm examples
---------------------------------
@@ -615,6 +688,8 @@ XLForm sets up `rowDescriptor` property using the `XLFormRowDescriptor` instance
The developer is responsible for update its views with the `rowDescriptor` value as well as set the selected value to `rowDescriptor` from within the custom selector view controller.
> Note: the properties `viewControllerClass`, `viewControllerNibName` or `viewControllerStoryboardId` are mutually exclusive and are used by `XLFormButtonCell` and `XLFormSelectorCell`. If you create a custom cell then you are responsible for using them.
#### Another example
@@ -804,7 +879,7 @@ Let's see how to change the color of the cell label:
```objc
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"title" rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:[UIColor redColor] forKey:@"textLabel.textColor"];
[row.cellConfig setObject:[UIColor redColor] forKey:@"textLabel.textColor"];
[section addFormRow:row];
```
@@ -999,6 +1074,15 @@ This is how you can set them:
[row.cellConfigAtConfigure setObject:@(UIReturnKeyGo) forKey:@"nextReturnKeyType"];
```
#### How to change the height of one cell
If you want to change the height for all cells of one class you should subclass that cell and override the class method `formDescriptorCellHeightForRowDescriptor`.
If you want to change the height of one individual cell then you can set that height to the `height` property of XLFormRowDescripto like this:
```
XLFormRowDescriptor* row = ...
row.height = 55;
```
Installation
--------------------------
@@ -1010,15 +1094,7 @@ Installation
XLForm **has no** dependencies over other pods.
## Carthage
In your `Cartfile` add:
```
github "xmartlabs/XLForm" ~> 3.0
```
### How to use master branch
#### How to use master branch
Often master branch contains most recent features and latest fixes. On the other hand this features was not fully tested and changes on master may occur at any time. For the previous reasons I stongly recommend to fork the repository and manage the updates from master on your own making the proper pull on demand.
@@ -1029,7 +1105,7 @@ To use xmartlabs master branch.....
You can replace the repository URL for your forked version url if you wish.
### How to use XLForm in Swift files
#### How to use XLForm in Swift files
If you have installed XLForm with cocoapods and have set `use_frameworks!` in your Podfile, you can add `import XLForm` to any Swift file.
@@ -1037,6 +1113,31 @@ If you are using cocoapods but have not set `use_frameworks!` in your Podfile, a
For further details on how to create and configure the bridging header file visit [*Importing Objective-C into Swift*](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html "Importing Objective-C into Swift").
## Carthage
In your `Cartfile` add:
```
github "xmartlabs/XLForm" ~> 3.0
```
## Using git submodules
* Clone XLForm as a git [submodule](http://git-scm.com/docs/git-submodule) by running the following command from your project root git folder.
```bash
$ git submodule add https://github.com/xmartlabs/XLForm.git
```
* Open XLForm folder that was created by the previous git submodule command and drag the XLForm.xcodeproj into the Project Navigator of your application's Xcode project.
* Select the XLForm.xcodeproj in the Project Navigator and verify the deployment target matches with your application deployment target.
* Select your project in the Xcode Navigation and then select your application target from the sidebar. Next select the "General" tab and click on the + button under the "Embedded Binaries" section.
* Select `XLForm.framework` and we are done!
Requirements
-----------------------------
@@ -1048,7 +1149,7 @@ Requirements
Release Notes
--------------
Have a look at the [CHANGELOG](https://github.com/xmartlabs/XLForm/CHANGELOG.md)
Have a look at the [CHANGELOG](https://github.com/xmartlabs/XLForm/blob/master/CHANGELOG.md)
Author
-----------------
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'XLForm'
s.version = '3.1.1'
s.version = '3.2.0'
s.license = { :type => 'MIT' }
s.summary = 'XLForm is the most flexible and powerful iOS library to create dynamic table-view forms.'
s.description = <<-DESC
+1 -1
View File
@@ -561,7 +561,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 3.0.2;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -228,6 +228,7 @@
[self.formViewController presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self cancelButtonTitle:nil
@@ -244,6 +245,7 @@
}
#endif
#endif
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
+17 -7
View File
@@ -143,7 +143,7 @@
self.editingAccessoryType = self.accessoryType;
self.selectionStyle = self.rowDescriptor.isDisabled || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeInfo] ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleDefault;
self.textLabel.text = [NSString stringWithFormat:@"%@%@", self.rowDescriptor.title, self.rowDescriptor.required && self.rowDescriptor.sectionDescriptor.formDescriptor.addAsteriskToRequiredRowsTitle ? @"*" : @""];
self.detailTextLabel.text = [self valueDisplayText];
self.detailTextLabel.text = [self valueDisplayText];
}
-(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller
@@ -166,7 +166,7 @@
UIViewController<XLFormRowDescriptorViewController> *selectorViewController = (UIViewController<XLFormRowDescriptorViewController> *)controllerToPresent;
selectorViewController.rowDescriptor = self.rowDescriptor;
selectorViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
if (self.popoverController && self.popoverController.popoverVisible) {
[self.popoverController dismissPopoverAnimated:NO];
@@ -192,7 +192,7 @@
XLFormOptionsViewController * optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil];
optionsViewController.rowDescriptor = self.rowDescriptor;
optionsViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
self.popoverController.delegate = self;
@@ -212,10 +212,16 @@
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover])
{
NSAssert(self.rowDescriptor.selectorOptions, @"selectorOptions property shopuld not be nil");
XLFormOptionsViewController * optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil];
UIViewController * controllerToPresent = nil;
XLFormOptionsViewController * optionsViewController = nil;
if ((controllerToPresent = [self controllerToPresent])){
optionsViewController = (XLFormOptionsViewController *)controllerToPresent;
} else {
optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil];
}
optionsViewController.rowDescriptor = self.rowDescriptor;
optionsViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) {
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
self.popoverController.delegate = self;
@@ -232,8 +238,8 @@
}
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
@@ -269,6 +275,7 @@
}
[formViewController presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
@@ -282,6 +289,7 @@
actionSheet.tag = [self.rowDescriptor hash];
[actionSheet showInView:controller.view];
}
#endif
#endif
[controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
}
@@ -319,6 +327,7 @@
[controller presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:self.rowDescriptor.selectorTitle
message:nil
@@ -332,6 +341,7 @@
alertView.tag = [self.rowDescriptor hash];
[alertView show];
}
#endif
#endif
[controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
}
+64 -18
View File
@@ -147,7 +147,7 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
self.textLabel.text = ((self.rowDescriptor.required && self.rowDescriptor.title && self.rowDescriptor.sectionDescriptor.formDescriptor.addAsteriskToRequiredRowsTitle) ? [NSString stringWithFormat:@"%@*", self.rowDescriptor.title] : self.rowDescriptor.title);
self.textField.text = self.rowDescriptor.value ? [self.rowDescriptor.value displayText] : self.rowDescriptor.noValueDisplayText;
self.textField.text = self.rowDescriptor.value ? [self.rowDescriptor displayTextValue] : self.rowDescriptor.noValueDisplayText;
[self.textField setEnabled:!self.rowDescriptor.isDisabled];
self.textField.textColor = self.rowDescriptor.isDisabled ? [UIColor grayColor] : [UIColor blackColor];
self.textField.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
@@ -200,8 +200,14 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
[self.textLabel setContentCompressionResistancePriority:1000 forAxis:UILayoutConstraintAxisHorizontal];
// Add Constraints
[result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=11)-[_textField]-(>=11)-|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(_textField)]];
[result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=11)-[_textLabel]-(>=11)-|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:NSDictionaryOfVariableBindings(_textLabel)]];
[result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_textField]-(margin)-|"
options:NSLayoutFormatAlignAllBaseline
metrics:[NSDictionary dictionaryWithObjectsAndKeys:@(11.0), @"margin", nil]
views:NSDictionaryOfVariableBindings(_textField)]];
[result addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_textLabel]-(margin)-|"
options:NSLayoutFormatAlignAllBaseline
metrics:[NSDictionary dictionaryWithObjectsAndKeys:@(11.0), @"margin", nil]
views:NSDictionaryOfVariableBindings(_textLabel)]];
return result;
}
@@ -211,10 +217,18 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
if (self.dynamicCustomConstraints){
[self.contentView removeConstraints:self.dynamicCustomConstraints];
}
NSDictionary * views = @{@"label": self.textLabel, @"textField": self.textField, @"image": self.imageView};
NSMutableDictionary * views = [[NSMutableDictionary alloc] initWithDictionary: @{@"label": self.textLabel, @"textField": self.textField}];
if (self.imageView.image){
views[@"image"] = self.imageView;
if (self.textLabel.text.length > 0){
self.dynamicCustomConstraints = [NSMutableArray arrayWithArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[image]-[label]-[textField]-|" options:0 metrics:nil views:views]];
[self.dynamicCustomConstraints addObject:[NSLayoutConstraint constraintWithItem:_textField
attribute:NSLayoutAttributeWidth
relatedBy:self.textFieldLengthPercentage ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
toItem:self.contentView
attribute:NSLayoutAttributeWidth
multiplier:self.textFieldLengthPercentage ? [self.textFieldLengthPercentage floatValue] : 0.3
constant:0.0]];
}
else{
self.dynamicCustomConstraints = [NSMutableArray arrayWithArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[image]-[textField]-|" options:0 metrics:nil views:views]];
@@ -223,20 +237,19 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
else{
if (self.textLabel.text.length > 0){
self.dynamicCustomConstraints = [NSMutableArray arrayWithArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-[textField]-|" options:0 metrics:nil views:views]];
[self.dynamicCustomConstraints addObject:[NSLayoutConstraint constraintWithItem:_textField
attribute:NSLayoutAttributeWidth
relatedBy:self.textFieldLengthPercentage ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
toItem:self.contentView
attribute:NSLayoutAttributeWidth
multiplier:self.textFieldLengthPercentage ? [self.textFieldLengthPercentage floatValue] : 0.3
constant:0.0]];
}
else{
self.dynamicCustomConstraints = [NSMutableArray arrayWithArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[textField]-|" options:0 metrics:nil views:views]];
}
}
[self.dynamicCustomConstraints addObject:[NSLayoutConstraint constraintWithItem:_textField
attribute:NSLayoutAttributeWidth
relatedBy:self.textFieldLengthPercentage ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
toItem:self.contentView
attribute:NSLayoutAttributeWidth
multiplier:self.textFieldLengthPercentage ? [self.textFieldLengthPercentage floatValue] : 0.3
constant:0.0]];
[self.contentView addConstraints:self.dynamicCustomConstraints];
[super updateConstraints];
}
@@ -272,11 +285,22 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
{
[self.formViewController beginEditing:self.rowDescriptor];
[self.formViewController textFieldDidBeginEditing:textField];
// set the input to the raw value if we have a formatter and it shouldn't be used during input
if (self.rowDescriptor.valueFormatter) {
self.textField.text = [self.rowDescriptor editTextValue];
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// process text change before we stick a formatted value in the UITextField
[self textFieldDidChange:textField];
// losing input, replace the text field with the formatted value
if (self.rowDescriptor.valueFormatter) {
self.textField.text = [self.rowDescriptor.value displayText];
}
[self.formViewController endEditing:self.rowDescriptor];
[self.formViewController textFieldDidEndEditing:textField];
}
@@ -286,12 +310,33 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
- (void)textFieldDidChange:(UITextField *)textField{
if([self.textField.text length] > 0) {
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeNumber] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDecimal]){
self.rowDescriptor.value = @([self.textField.text doubleValue]);
} else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeInteger]){
self.rowDescriptor.value = @([self.textField.text integerValue]);
} else {
self.rowDescriptor.value = self.textField.text;
BOOL didUseFormatter = NO;
if (self.rowDescriptor.valueFormatter && self.rowDescriptor.useValueFormatterDuringInput)
{
// use generic getObjectValue:forString:errorDescription and stringForObjectValue
NSString *errorDescription = nil;
NSString *objectValue = nil;
if ([ self.rowDescriptor.valueFormatter getObjectValue:&objectValue forString:textField.text errorDescription:&errorDescription]) {
NSString *formattedValue = [self.rowDescriptor.valueFormatter stringForObjectValue:objectValue];
self.rowDescriptor.value = objectValue;
textField.text = formattedValue;
didUseFormatter = YES;
}
}
// only do this conversion if we didn't use the formatter
if (!didUseFormatter)
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeNumber] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDecimal]){
self.rowDescriptor.value = [NSDecimalNumber decimalNumberWithString: self.textField.text];
} else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeInteger]){
self.rowDescriptor.value = @([self.textField.text integerValue]);
} else {
self.rowDescriptor.value = self.textField.text;
}
}
} else {
self.rowDescriptor.value = nil;
@@ -309,4 +354,5 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
return _returnKeyType;
}
@end
+4
View File
@@ -206,4 +206,8 @@ NSString *const XLFormTextViewLengthPercentage = @"textViewLengthPercentage";
}
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
return [self.formViewController textView:textView shouldChangeTextInRange:range replacementText:text];
}
@end
+14 -6
View File
@@ -479,6 +479,7 @@
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"XLFormViewController_ValidationErrorTitle", nil)
message:error.localizedDescription
@@ -488,6 +489,7 @@
[alertView show];
}
#endif
#endif
}
-(void)performFormSelector:(SEL)selector withObject:(id)sender
@@ -722,9 +724,10 @@
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
XLFormRowDescriptor *rowDescriptor = [self.form formRowAtIndex:indexPath];
Class cellClass = [[rowDescriptor cellForFormController:self] class];
if ([cellClass respondsToSelector:@selector(formDescriptorCellHeightForRowDescriptor:)]){
return [cellClass formDescriptorCellHeightForRowDescriptor:rowDescriptor];
[rowDescriptor cellForFormController:self];
CGFloat height = rowDescriptor.height;
if (height != XLFormUnspecifiedCellHeight){
return height;
}
return self.tableView.rowHeight;
}
@@ -732,9 +735,10 @@
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
XLFormRowDescriptor *rowDescriptor = [self.form formRowAtIndex:indexPath];
Class cellClass = [[rowDescriptor cellForFormController:self] class];
if ([cellClass respondsToSelector:@selector(formDescriptorCellHeightForRowDescriptor:)]){
return [cellClass formDescriptorCellHeightForRowDescriptor:rowDescriptor];
[rowDescriptor cellForFormController:self];
CGFloat height = rowDescriptor.height;
if (height != XLFormUnspecifiedCellHeight){
return height;
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")){
return self.tableView.estimatedRowHeight;
@@ -900,6 +904,10 @@
{
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
return YES;
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
+12 -1
View File
@@ -29,6 +29,8 @@
#import "XLFormValidatorProtocol.h"
#import "XLFormValidationStatus.h"
extern CGFloat XLFormUnspecifiedCellHeight;
@class XLFormViewController;
@class XLFormSectionDescriptor;
@protocol XLFormValidatorProtocol;
@@ -52,8 +54,17 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
@property (nonatomic, nullable) id value;
@property (nullable) Class valueTransformer;
@property UITableViewCellStyle cellStyle;
@property (nonatomic) CGFloat height;
@property (copy, nullable) XLOnChangeBlock onChangeBlock;
@property BOOL useValueFormatterDuringInput;
@property (nullable) NSFormatter *valueFormatter;
// returns the display text for the row descriptor, taking into account NSFormatters and default placeholder values
- (nonnull NSString *) displayTextValue;
// returns the editing text value for the row descriptor, taking into account NSFormatters.
- (nonnull NSString *) editTextValue;
@property (nonatomic, readonly, nonnull) NSMutableDictionary * cellConfig;
@property (nonatomic, readonly, nonnull) NSMutableDictionary * cellConfigIfDisabled;
@@ -78,7 +89,7 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
@property (nullable) NSString *requireMsg;
-(void)addValidator:(nonnull id<XLFormValidatorProtocol>)validator;
-(void)removeValidator:(nonnull id<XLFormValidatorProtocol>)validator;
-(nonnull XLFormValidationStatus *)doValidation;
-(nullable XLFormValidationStatus *)doValidation;
// ===========================
// property used for Selectors
+61 -2
View File
@@ -28,6 +28,9 @@
#import "XLFormRowDescriptor.h"
#import "NSString+XLFormAdditions.h"
CGFloat XLFormUnspecifiedCellHeight = -1.0;
CGFloat XLFormRowInitialHeight = -2;
@interface XLFormDescriptor (_XLFormRowDescriptor)
@property (readonly) NSDictionary* allRowsByTag;
@@ -44,6 +47,8 @@
@end
#import "NSObject+XLFormAdditions.h"
@interface XLFormRowDescriptor() <NSCopying>
@property XLFormBaseCell * cell;
@@ -66,6 +71,7 @@
@synthesize cellConfig = _cellConfig;
@synthesize cellConfigIfDisabled = _cellConfigIfDisabled;
@synthesize cellConfigAtConfigure = _cellConfigAtConfigure;
@synthesize height = _height;
-(instancetype)init
{
@@ -91,6 +97,7 @@
_disablePredicateCache = nil;
_isDirtyHidePredicateCache = YES;
_hidePredicateCache = nil;
_height = XLFormRowInitialHeight;
[self addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
[self addObserver:self forKeyPath:@"disablePredicateCache" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
[self addObserver:self forKeyPath:@"hidePredicateCache" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
@@ -172,6 +179,41 @@
return _cellConfigAtConfigure;
}
-(NSString*)editTextValue
{
if (self.value) {
if (self.valueFormatter) {
if (self.useValueFormatterDuringInput) {
return [self displayTextValue];
}else{
// have formatter, but we don't want to use it during editing
return [self.value displayText];
}
}else{
// have value, but no formatter, use the value's displayText
return [self.value displayText];
}
}else{
// placeholder
return @"";
}
}
-(NSString*)displayTextValue
{
if (self.value) {
if (self.valueFormatter) {
return [self.valueFormatter stringForObjectValue:self.value];
}
else{
return [self.value displayText];
}
}
else {
return self.noValueDisplayText;
}
}
-(NSString *)description
{
return self.tag; // [NSString stringWithFormat:@"%@ - %@ (%@)", [super description], self.tag, self.rowType];
@@ -190,6 +232,22 @@
_action = action;
}
-(CGFloat)height
{
if (_height == XLFormRowInitialHeight){
if ([[self.cell class] respondsToSelector:@selector(formDescriptorCellHeightForRowDescriptor:)]){
return [[self.cell class] formDescriptorCellHeightForRowDescriptor:self];
} else {
_height = XLFormUnspecifiedCellHeight;
}
}
return _height;
}
-(void)setHeight:(CGFloat)height {
_height = height;
}
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
@@ -203,7 +261,7 @@
rowDescriptorCopy.required = self.isRequired;
rowDescriptorCopy.isDirtyDisablePredicateCache = YES;
rowDescriptorCopy.isDirtyHidePredicateCache = YES;
rowDescriptorCopy.validators = [self.validators copy];
rowDescriptorCopy.validators = [self.validators mutableCopy];
// =====================
// properties for Button
@@ -427,7 +485,8 @@
- (BOOL)valueIsEmpty
{
return self.value == nil || [self.value isKindOfClass:[NSNull class]] || ([self.value respondsToSelector:@selector(length)] && [self.value length]==0);
return self.value == nil || [self.value isKindOfClass:[NSNull class]] || ([self.value respondsToSelector:@selector(length)] && [self.value length]==0) ||
([self.value respondsToSelector:@selector(count)] && [self.value count]==0);
}
-(XLFormValidationStatus *)doValidation
+3 -3
View File
@@ -31,12 +31,12 @@
-(NSString *)displayText
{
if ([self isKindOfClass:[NSString class]] || [self isKindOfClass:[NSNumber class]]){
return [self description];
}
if ([self conformsToProtocol:@protocol(XLFormOptionObject)]){
return [(id<XLFormOptionObject>)self formDisplayText];
}
if ([self isKindOfClass:[NSString class]] || [self isKindOfClass:[NSNumber class]]){
return [self description];
}
return nil;
}