55 Commits

Author SHA1 Message Date
Mathias Claassen 6ac31155f8 release 4.0.1 (#1049) 2019-04-15 11:07:06 -03:00
Liraz S 151003d8e5 Memory and stability fixes to XLForm (#1045)
* selectorCell display repair

Unable to display when value than apples first selectorOptions

* fixed crash

* fixed memory leaks

* Cell disappears while inline picker is open

* Fixes crash on update

* check object object equal

* codereview

* fixed memory leaks

* fixed memory leaks [2]

* updated logic

* fixed memory leaks

* fix for crash #1043

* fix for crash #1044

* fix for issue #1044

* fix for issue #1044

* fixed mistake

* fixed observation if lib uses in drawer controller

* fixed kvo crash

* reverted last fix

* cleanup

* fixed kvo

* fix for crash #1043

* reverted https://github.com/xmartlabs/XLForm/pull/1045#discussion_r255965033

* reverted #948

* fixed firstResponder logic

* codereview in Descriptors

* codereview
2019-03-25 12:20:16 -03:00
Mathias Claassen b5bdda8e80 Update Readme (#1046) 2019-03-14 13:40:30 -03:00
Bruno Agatte 81aca9c49c Update XLFormRowDescriptor.m to support <Class>.self for custom cells (#1041) 2019-01-08 10:59:18 -03:00
Ju d8ece1410d Fix crash when using swift custom cells with xib files (#1038) (#1040) 2019-01-07 15:57:31 -03:00
Nikita Razumnuy fdca5f7543 fix: can't update placeholder color using setNeedsDisplay in XLFormTextView (#1024) 2018-08-23 11:20:17 -03:00
Martin Barreto 204cad6045 update swift example 2017-10-26 14:36:33 -03:00
Martin Barreto e68b57cded update XLForm tests 2017-10-26 14:36:33 -03:00
Martin Barreto 0bc600d5a7 fix travis 2017-10-26 14:36:33 -03:00
pera c2d721f098 minor fixes 2017-10-26 14:36:33 -03:00
pera 2485332846 Updates README.md, CHANGELOG.md & podspec. 2017-10-26 14:36:33 -03:00
pera 20b661c41e - Adds support for Xcode9
- Deprecation of UIAlertView, UIActionSheet & UIPopoverController
2017-10-26 14:36:33 -03:00
MiMo42 1e2b5137d6 Fixed crash when trying to insert row in section at index 0 (#964) 2017-06-08 11:47:26 -03:00
Miguel Revetria 43abac5c3f Fixes #893, setting rowDescriptor to the serach result controller (#961) 2017-05-25 10:20:36 -03:00
MiMo42 77db6b9492 nullability warning fixed (#952) 2017-04-26 10:21:35 -03:00
Mathias Claassen 74b26c1e64 make properties of XLFormOptionsObject writable (#955) 2017-04-25 11:55:54 -03:00
Mathias Claassen 085cf31e52 Updated Readme Eureka introduction (#954) 2017-04-25 10:48:47 -03:00
FatalDizz 313e5d5d40 Added method to set a title for form errors (#951) 2017-04-19 11:46:34 -03:00
Mathias Claassen f7777d9d27 Add Header and Footer section to Readme FAQ (#942) 2017-04-05 09:46:52 -03:00
Mathias Claassen 578dea99dd Use the correct locale in date row (not only date picker) (#935) 2017-04-05 09:23:41 -03:00
Santiago Castro 1da30107dc Fix README headings due to GitHub change (#937)
GitHub changed its Markdown processor to stop supporting heading without spaces https://gist.github.com/vmarkovtsev/59cd7349d41cf804b9a8775388e681f8
2017-03-21 09:18:22 -03:00
Mathias Claassen 4674c3abaf Make moveRowAtIndexPath:toIndexPath: public in XLFormSectionDescriptor to allow to reorder rows programmatically. (#929) 2017-02-22 12:58:47 -03:00
Felix Dumit 5ca54fd949 Fix use of formatter in Info Cells (#916)
Adds example with infocell and bytecount formatter
2017-01-16 18:15:42 -03:00
Mathias Claassen e64e5b4885 update Travis file to use Xcode 8.2 (#920) 2017-01-12 10:24:37 -03:00
Mathias Claassen b28c902d73 release version 3.3.0 2016-11-17 11:10:10 -03:00
Mathias Claassen dc5f1e6dcd Merge pull request #895 from dvkch/master
Fix for #884
2016-11-03 11:33:16 -03:00
Stanislas Chevallier 55e440bc57 Fix: #884 by setting the UIDatePicker timeZone to GMT+0 when in countdown mode 2016-11-02 13:42:51 +01:00
Martin Barreto be2fb864be Update README.md 2016-10-21 18:14:17 -03:00
Mathias Claassen cdd498ebc7 Merge pull request #866 from xmartlabs/Swift3
Update Swift example to Swift 3 syntax
2016-10-20 14:46:21 -03:00
Mathias Claassen cd43abc3f0 Merge pull request #882 from kiancheong/OptionsRow-Deselect
OptionsRow-Deselect
2016-10-18 16:06:49 -03:00
kiancheong f1a83512d1 Prevents setting cell's accessoryType to UITableViewCellAccessoryNone if the rowDescriptor's required value is true.
This fixes the ability to deselect options when using XLFormRowDescriptorTypeSelectorPush.
2016-10-14 09:08:25 +08:00
Mathias Claassen 00ccf60895 Merge pull request #883 from kiancheong/bigsprocket-styling
bigsprocket-styling
2016-10-13 10:57:39 -03:00
kiancheong 27a172eb65 Synthesize cellConfigForSelector. 2016-10-11 19:31:45 +08:00
Kyle Davis e62404d24b remove unnecessary nil check 2016-10-11 12:57:16 +08:00
Kyle Davis d1aff91e63 Support styling of XLFormOptionViewController cells 2016-10-11 12:57:14 +08:00
Mathias Claassen a0a8cf793c Update Swift example to Swift 3 syntax 2016-09-15 13:33:38 -03:00
Mathias Claassen bb81e88572 Merge pull request #864 from choefele/master
Limit number of characters in XLFormTextFieldCell and XLFormTextViewCell
2016-09-07 10:31:50 -03:00
Claus Höfele 64ab7ccac0 Add property in XLFormTextViewCell to limit number of characters 2016-09-05 20:37:57 +02:00
Claus Höfele 9baeda1b0d Add property in XLFormTextFieldCell to limit number of characters
Implements #855
2016-09-05 18:52:23 +02:00
Mathias Claassen 6879f01230 Merge pull request #832 from xmartlabs/fix/constant
change XLFormUnspecifiedHeight constant to not collide with Automatic…
2016-07-22 11:34:30 -03:00
Mathias Claassen 50e9efe783 change XLFormUnspecifiedHeight constant to not collide with Automatic dimension 2016-07-22 11:34:01 -03:00
Mathias Claassen bf819ba0ed Merge pull request #831 from ablexie/master
Add locale property to date cell for inline cells
2016-07-22 11:26:50 -03:00
ablexie 087bbf089c datePicker.locale property public to developer,for example,
_birthdayRow = [XLFormRowDescriptor formRowDescriptorWithTag:kBirthdayTag rowType:XLFormRowDescriptorTypeDateInline title:@"Birthday"];
[_birthdayRow.cellConfig setObject:[[NSLocale alloc] initWithLocaleIdentifier:@"en"] forKey:@"locale"];
2016-07-21 10:29:17 +08:00
Mathias Claassen eac2f816d7 Merge pull request #819 from 3a4oT/master
Refactored '-(id)init..' to '- (instancetype)init...'
2016-07-07 11:23:43 -03:00
Mathias Claassen b19bf9bafc Merge pull request #817 from 3a4oT/patch-2
Update 'initializeForm' example.
2016-07-07 11:18:00 -03:00
Petro Rovenskyy ce869235bc Refactored '-(id)init' to '- (instancetype)init' 2016-07-04 21:50:17 +03:00
Petro Rovenskyy bb93c90c2d Update 'initializeForm' example.
Copy and paste the example of  ```initializeForm``` and feel the power of XLForm immediately. =)
2016-07-01 15:47:22 +03:00
Mathias Claassen 7b50e19cf6 Merge pull request #814 from 3a4oT/patch-1
Update pod badge
2016-06-30 10:12:56 -03:00
Petro Rovenskyy 8eefa8afd9 Update pod badge 2016-06-30 15:27:48 +03:00
Mathias Claassen ca53315145 Merge pull request #810 from jeanmartin/master
[fixes #452] respect the currentLocale when parsing decimal values
2016-06-28 09:44:14 -03:00
Jan Schwenzien c3263f7645 [fixes #452] respect the currentLocale when parsing decimal values 2016-06-27 22:04:51 +02:00
Mathias Claassen fbf800fc21 Merge pull request #806 from jimmyti/master
Fixed selector action sheet to use the row's value transformer
2016-06-24 09:54:33 -03:00
Jimmy Ti fbc08a7094 Remove the fix for suppressing "Empty snapshot" warnings when presenting action sheets 2016-06-23 23:10:57 +10:00
Jimmy Ti f1f8a21bf0 Updated code to actually use the optionTitle variable 2016-06-21 00:18:33 +10:00
Jimmy Ti 694c08beee Fixed selector action sheet to use the row's value transformer 2016-06-20 21:19:20 +10:00
99 changed files with 2132 additions and 1878 deletions
+2 -4
View File
@@ -19,7 +19,5 @@ DerivedData
#CocoaPods
Pods
Tests/Pods
Tests/Podfile.lock
Examples/Objective-C/Podfile.lock
Examples/Swift/Podfile.lock
Podfile.lock
*.xcworkspace
+3 -3
View File
@@ -1,8 +1,8 @@
language: objective-c
osx_image: xcode7.2
osx_image: xcode10.2
before_install:
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
- gem install cocoapods --quiet
- gem install xcpretty --quiet
- cd Tests && pod install && cd $TRAVIS_BUILD_DIR
script: rake test
+16 -2
View File
@@ -1,7 +1,21 @@
# Change Log
All notable changes to this project will be documented in this file.
### Latest:
### Version 4.0.1:
* Memory improvements and fixes.
* Other minor fixes
### Version 4.0.0:
* Adds support for Xcode 9.
* Deprecated UIAlertView, UIActionSheet, UIPopoverController.
* Bumped minimum iOS version to 9.0.
### Version 3.3.0:
* Added `cellConfigForSelector` to style XLFormOptionsViewController
* Added properties to **limit number of characters** in `XLFormTextFieldCell` and `XLFormTextViewCell`
* Minor fixes
### Version 3.2.0:
* 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)
@@ -129,4 +143,4 @@ All notable changes to this project will be documented in this file.
### Version 1.0.0
* Initial release
* Initial release
@@ -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
@@ -153,38 +154,13 @@ NSString *const kCountDownTimer = @"countDownTimer";
-(void)formRowDescriptorValueHasChanged:(XLFormRowDescriptor *)formRow oldValue:(id)oldValue newValue:(id)newValue
{
// super implementation must be called
[super formRowDescriptorValueHasChanged:formRow oldValue:oldValue newValue:newValue];
if([formRow.tag isEqualToString:kDatePicker])
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"DatePicker"
message:@"Value Has changed!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[message show];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"DatePicker"
message:@"Value Has changed!"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
else{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"DatePicker"
message:@"Value Has changed!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[message show];
}
#endif
}
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"DatePicker"
message:@"Value Has changed!"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
@@ -21,7 +21,7 @@
// http://stackoverflow.com/questions/12580162/nsstring-to-nsdate-conversion-issue
@interface CurrencyFormatter : NSNumberFormatter
@property (readonly) NSDecimalNumberHandler *roundingBehavior;
@property (readonly, strong) NSDecimalNumberHandler *roundingBehavior;
@end
@@ -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];
@@ -112,4 +117,4 @@
}
@end
@end
@@ -135,33 +135,13 @@ NSString *const kNotes = @"notes";
}
[self.tableView endEditing:YES];
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Valid Form", nil)
message:@"No errors found"
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
#else
if ([UIAlertController class]){
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Valid Form", nil)
message:@"No errors found"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
else{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Valid Form", nil)
message:@"No errors found"
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
}
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Valid Form", nil)
message:@"No errors found"
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
@@ -25,7 +25,7 @@
#import "XLForm.h"
#import "SelectorsFormViewController.h"
#import "MultiValuedFormViewController.h"
#import "MultivaluedFormViewController.h"
@implementation MultivaluedFormViewController
@@ -85,95 +85,45 @@
-(void)addDidTouch:(UIBarButtonItem * __unused)sender
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:NSLocalizedString(@"Cancel")
destructiveButtonTitle:@"Remove Last Section"
otherButtonTitles:@"Add a section at the end", self.form.isDisabled ? @"Enable Form" : @"Disable Form", nil];
[actionSheet showInView:self.view];
#else
if ([UIAlertController class]){
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak __typeof(self)weakSelf = self;
[alertController addAction:[UIAlertAction actionWithTitle:@"Remove Last Section"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
if (weakSelf.form.formSections.count > 0){
// remove last section
[weakSelf.form removeFormSectionAtIndex:(weakSelf.form.formSections.count - 1)];
}
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Add a section at the end"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// add a new section
XLFormSectionDescriptor * newSection = [XLFormSectionDescriptor formSectionWithTitle:[NSString stringWithFormat:@"Section created at %@", [NSDateFormatter localizedStringFromDate:[NSDate new] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]] sectionOptions:XLFormSectionOptionCanInsert | XLFormSectionOptionCanDelete];
newSection.multivaluedTag = [NSString stringWithFormat:@"multivaluedPushSelector_%@", @(weakSelf.form.formSections.count)];
XLFormRowDescriptor * newRow = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeSelectorPush title:@"Tap to select ;).."];
newRow.selectorOptions = @[@"Option 1", @"Option 2", @"Option 3"];
[newSection addFormRow:newRow];
[weakSelf.form addFormSection:newSection];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:self.form.isDisabled ? @"Enable Form" : @"Disable Form"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
weakSelf.form.disabled = !weakSelf.form.disabled;
[weakSelf.tableView endEditing:YES];
[weakSelf.tableView reloadData];
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
else{
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
destructiveButtonTitle:@"Remove Last Section"
otherButtonTitles:@"Add a section at the end", self.form.isDisabled ? @"Enable Form" : @"Disable Form", nil];
[actionSheet showInView:self.view];
}
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak __typeof(self)weakSelf = self;
[alertController addAction:[UIAlertAction actionWithTitle:@"Remove Last Section"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
if (weakSelf.form.formSections.count > 0){
// remove last section
[weakSelf.form removeFormSectionAtIndex:(weakSelf.form.formSections.count - 1)];
}
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Add a section at the end"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// add a new section
XLFormSectionDescriptor * newSection = [XLFormSectionDescriptor formSectionWithTitle:[NSString stringWithFormat:@"Section created at %@", [NSDateFormatter localizedStringFromDate:[NSDate new] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]] sectionOptions:XLFormSectionOptionCanInsert | XLFormSectionOptionCanDelete];
newSection.multivaluedTag = [NSString stringWithFormat:@"multivaluedPushSelector_%@", @(weakSelf.form.formSections.count)];
XLFormRowDescriptor * newRow = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeSelectorPush title:@"Tap to select ;).."];
newRow.selectorOptions = @[@"Option 1", @"Option 2", @"Option 3"];
[newSection addFormRow:newRow];
[weakSelf.form addFormSection:newSection];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:self.form.isDisabled ? @"Enable Form" : @"Disable Form"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
weakSelf.form.disabled = !weakSelf.form.disabled;
[weakSelf.tableView endEditing:YES];
[weakSelf.tableView reloadData];
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([actionSheet destructiveButtonIndex] == buttonIndex){
if (self.form.formSections.count > 0){
// remove last section
[self.form removeFormSectionAtIndex:(self.form.formSections.count - 1)];
}
}
else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Add a section at the end"]){
// add a new section
XLFormSectionDescriptor * newSection = [XLFormSectionDescriptor formSectionWithTitle:[NSString stringWithFormat:@"Section created at %@", [NSDateFormatter localizedStringFromDate:[NSDate new] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]] sectionOptions:XLFormSectionOptionCanInsert | XLFormSectionOptionCanDelete];
newSection.multivaluedTag = [NSString stringWithFormat:@"multivaluedPushSelector_%@", @(self.form.formSections.count)];
XLFormRowDescriptor * newRow = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeSelectorPush title:@"Tap to select ;).."];
newRow.selectorOptions = @[@"Option 1", @"Option 2", @"Option 3"];
[newSection addFormRow:newRow];
[self.form addFormSection:newSection];
}
else if (![[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:NSLocalizedString(@"Cancel")]){
self.form.disabled = !self.form.disabled;
[self.tableView endEditing:YES];
[self.tableView reloadData];
}
}
#endif
@end
@@ -32,7 +32,7 @@
NSString *const kFormImageSelectorCellDefaultImage = @"defaultImage";
NSString *const kFormImageSelectorCellImageRequest = @"imageRequest";
@interface XLFormImageSelectorCell() <UIActionSheetDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@interface XLFormImageSelectorCell() <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@property (nonatomic) UIImage * defaultImage;
@property (nonatomic) NSURLRequest * imageRequest;
@@ -92,57 +92,36 @@ NSString *const kFormImageSelectorCellImageRequest = @"imageRequest";
-(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
destructiveButtonTitle:nil
otherButtonTitles:NSLocalizedString(@"XLFormImageSelectorCell_ChooseExistingPhoto", @"Choose Existing Photo"), NSLocalizedString(@"XLFormImageSelectorCell_TakePicture", @"Take a Picture"), nil];
actionSheet.tag = self.tag;
[actionSheet showInView:self.formViewController.view];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak __typeof(self)weakSelf = self;
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"XLFormImageSelectorCell_ChooseExistingPhoto", @"Choose Existing Photo")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = weakSelf;
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[weakSelf.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"XLFormImageSelectorCell_TakePicture", @"Take a Picture")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = weakSelf;
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[weakSelf.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}]];
[self.formViewController presentViewController:alertController animated:YES completion:nil];
}
else{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
destructiveButtonTitle:nil
otherButtonTitles:NSLocalizedString(@"XLFormImageSelectorCell_ChooseExistingPhoto", @"Choose Existing Photo"), NSLocalizedString(@"XLFormImageSelectorCell_TakePicture", @"Take a Picture"), nil];
actionSheet.tag = self.tag;
[actionSheet showInView:self.formViewController.view];
}
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak __typeof(self)weakSelf = self;
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"XLFormImageSelectorCell_ChooseExistingPhoto", @"Choose Existing Photo")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = weakSelf;
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[weakSelf.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"XLFormImageSelectorCell_TakePicture", @"Take a Picture")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = weakSelf;
imagePickerController.allowsEditing = YES;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[weakSelf.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}]];
[self.formViewController presentViewController:alertController animated:YES completion:nil];
}
#pragma mark - LayoutConstraints
@@ -213,32 +192,6 @@ NSString *const kFormImageSelectorCellImageRequest = @"imageRequest";
[self.textLabel removeObserver:self forKeyPath:@"text"];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet * __unused)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;
if (buttonIndex == 0){
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[self.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}
else if (buttonIndex == 1){
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
[self.formViewController presentViewController:imagePickerController animated:YES completion:nil];
}
}
#endif
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
@@ -134,32 +134,13 @@ NSString *const kButtonWithStoryboardId = @"buttonWithStoryboardId";
__typeof(self) __weak weakSelf = self;
buttonLeftAlignedRow.action.formBlock = ^(XLFormRowDescriptor * sender){
if ([[sender.sectionDescriptor.formDescriptor formRowWithTag:kSwitchBool].value boolValue]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
delegate:weakSelf
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
else{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
delegate:weakSelf
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
}
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
[weakSelf deselectFormRow:sender];
};
@@ -196,33 +177,13 @@ NSString *const kButtonWithStoryboardId = @"buttonWithStoryboardId";
-(void)didTouchButton:(XLFormRowDescriptor *)sender
{
if ([[sender.sectionDescriptor.formDescriptor formRowWithTag:kSwitchBool].value boolValue]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
else{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[message show];
}
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Switch is ON", nil)
message:@"Button has checked the switch value..."
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
[self deselectFormRow:sender];
}
@@ -89,7 +89,7 @@
MKPinAnnotationView *pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:@"annotation"];
pinAnnotationView.pinColor = MKPinAnnotationColorRed;
pinAnnotationView.pinTintColor = [UIColor redColor];
pinAnnotationView.draggable = YES;
pinAnnotationView.animatesDrop = YES;
return pinAnnotationView;
@@ -26,9 +26,9 @@
#import "XLFormRowDescriptor.h"
#import "XLRemoteDataStoreController.h"
@interface UsersTableViewController : XLRemoteDataStoreController <XLFormRowDescriptorViewController, XLFormRowDescriptorPopoverViewController>
@interface UsersTableViewController : XLRemoteDataStoreController <XLFormRowDescriptorViewController>
@property BOOL isSearchResultsController;
@property NSLayoutConstraint *topConstraint;
@end
@end
@@ -124,7 +124,6 @@
@implementation UsersTableViewController
@synthesize rowDescriptor = _rowDescriptor;
@synthesize popoverController = __popoverController;
@synthesize searchController = _searchController;
@synthesize searchResultController = _searchResultController;
@@ -205,15 +204,16 @@ static NSString *const kCellIdentifier = @"CellIdentifier";
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dataItem = [self.dataStore dataAtIndexPath:indexPath];
self.rowDescriptor.value = dataItem;
if (self.popoverController){
[self.popoverController dismissPopoverAnimated:YES];
[self.popoverController.delegate popoverControllerDidDismissPopover:self.popoverController];
}
else if ([self.parentViewController isKindOfClass:[UINavigationController class]]){
UIViewController *popoverController = self.presentedViewController;
if (popoverController && popoverController.modalPresentationStyle == UIModalPresentationPopover) {
[self dismissViewControllerAnimated:YES completion:nil];
} else if ([self.parentViewController isKindOfClass:[UINavigationController class]]) {
[self.navigationController popViewControllerAnimated:YES];
} else if ([self.presentingViewController isKindOfClass:[UsersTableViewController class]]) {
[[self.presentingViewController navigationController] popViewControllerAnimated:YES];
}
}
@@ -243,10 +243,12 @@ static NSString *const kCellIdentifier = @"CellIdentifier";
-(UsersTableViewController *)searchResultController
{
if (_searchResultController) return _searchResultController;
_searchResultController = [[UsersTableViewController alloc]init];
UsersTableViewController *usersViewController = [[UsersTableViewController alloc] init];
usersViewController.rowDescriptor = self.rowDescriptor;
_searchResultController = usersViewController;
_searchResultController.dataLoader.limit = 0; // no paging in search result
_searchResultController.isSearchResultsController = YES;
return _searchResultController;
}
@end
@end
+2 -2
View File
@@ -1,5 +1,5 @@
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
platform :ios, '9.0'
target 'XLForm' do
@@ -11,4 +11,4 @@ pod 'XLData', :git => 'https://github.com/xmartlabs/XLData.git', :commit => '1f9
pod 'JVFloatLabeledTextField', '1.0.2', :inhibit_warnings => true
pod 'AXRatingView', '1.0.3', :inhibit_warnings => true
pod 'SHSPhoneComponent'
end
end
+12 -5
View File
@@ -43,7 +43,7 @@ PODS:
- XLData/RemoteDataStore (2.0.0):
- XLData/CoreRemote
- XLData/DataStore
- XLForm (3.1.2)
- XLForm (4.0.1)
DEPENDENCIES:
- AFNetworking (~> 2.0)
@@ -53,12 +53,19 @@ DEPENDENCIES:
- XLData (from `https://github.com/xmartlabs/XLData.git`, commit `1f9019b56242a2019c7f7e11ec4ef823c397ebcf`)
- XLForm (from `../../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- AFNetworking
- AXRatingView
- JVFloatLabeledTextField
- SHSPhoneComponent
EXTERNAL SOURCES:
XLData:
:commit: 1f9019b56242a2019c7f7e11ec4ef823c397ebcf
:git: https://github.com/xmartlabs/XLData.git
XLForm:
:path: ../../
:path: "../../"
CHECKOUT OPTIONS:
XLData:
@@ -71,8 +78,8 @@ SPEC CHECKSUMS:
JVFloatLabeledTextField: 58a3a32cfb800e5b224f676987e7c13abf50a14d
SHSPhoneComponent: 4cec0653a150ad63cbc52b0c8b29ce2d3c9c26f0
XLData: df725c6179e2e0c80bf56a1ecad9afd169707a6d
XLForm: 6bb3c20857e2983cf494cb8b4d666c2a24673d5e
XLForm: b8d47a9a00fb6166981cb40de7169d70d611e9be
PODFILE CHECKSUM: 80615792e859be64c95add3bb57c1596234faf95
PODFILE CHECKSUM: 64fbcd03a2c13762b2c18e3938cc8008807937c9
COCOAPODS: 1.0.0
COCOAPODS: 1.6.0
@@ -482,12 +482,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 2850C62418D0F707002B7D0A /* Build configuration list for PBXNativeTarget "XLForm" */;
buildPhases = (
EBE0335CCC7588D83B89A92A /* 📦 Check Pods Manifest.lock */,
EBE0335CCC7588D83B89A92A /* [CP] Check Pods Manifest.lock */,
2850C5F418D0F706002B7D0A /* Sources */,
2850C5F518D0F706002B7D0A /* Frameworks */,
2850C5F618D0F706002B7D0A /* Resources */,
32EB30E0A90A4E91864B1D3C /* 📦 Embed Pods Frameworks */,
DE3D12F5596780A66C6C3D4A /* 📦 Copy Pods Resources */,
DE3D12F5596780A66C6C3D4A /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -504,7 +503,7 @@
2850C5F018D0F706002B7D0A /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = Xmartlabs;
};
buildConfigurationList = 2850C5F318D0F706002B7D0A /* Build configuration list for PBXProject "XLForm" */;
@@ -542,49 +541,40 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
32EB30E0A90A4E91864B1D3C /* 📦 Embed Pods Frameworks */ = {
DE3D12F5596780A66C6C3D4A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh",
"${PODS_ROOT}/../../../XLForm/XLForm.bundle",
);
name = "📦 Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/XLForm.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
DE3D12F5596780A66C6C3D4A /* 📦 Copy Pods Resources */ = {
EBE0335CCC7588D83B89A92A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "📦 Copy Pods Resources";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-XLForm-checkManifestLockResult.txt",
);
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;
shellPath = /bin/sh;
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";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -658,19 +648,32 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -683,7 +686,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
@@ -697,25 +700,38 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
@@ -730,7 +746,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "XLForm/XLForm-Prefix.pch";
INFOPLIST_FILE = "XLForm/XLForm-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
@@ -748,7 +764,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "XLForm/XLForm-Prefix.pch";
INFOPLIST_FILE = "XLForm/XLForm-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@@ -48,6 +58,16 @@
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
@@ -101,8 +121,13 @@
"scale" : "2x"
},
{
"idiom" : "car",
"size" : "120x120",
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
@@ -142,8 +167,15 @@
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
"role" : "appLauncher",
"subtype" : "40mm"
},
{
"size" : "50x50",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "44mm"
},
{
"size" : "86x86",
@@ -158,6 +190,30 @@
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
},
{
"size" : "108x108",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "44mm"
},
{
"idiom" : "watch-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"idiom" : "car",
"size" : "120x120",
"scale" : "1x"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
}
],
"info" : {
+1 -1
View File
@@ -1,4 +1,4 @@
platform :ios, '8.0'
platform :ios, '9.0'
target 'SwiftExample' do
@@ -38,8 +38,8 @@
28D8326C1AEC177E009E3B3F /* ValidationExamplesFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D8326B1AEC177E009E3B3F /* ValidationExamplesFormViewController.swift */; };
28D8326F1AEC2D1B009E3B3F /* UICustomizationFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D8326E1AEC2D1B009E3B3F /* UICustomizationFormViewController.swift */; };
28F490221AAFBBC600C8E0CC /* DatesFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F490211AAFBBC600C8E0CC /* DatesFormViewController.swift */; };
649437BA8D5B7C59BBDB7B92 /* libPods-SwiftExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E006C7F7FF8E967AA8661BC9 /* libPods-SwiftExample.a */; };
BF01E92B1C21FF2800BDE045 /* InlineSegmentedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF01E92A1C21FF2800BDE045 /* InlineSegmentedCell.swift */; };
DD7B43598E698717584375E9 /* libPods-SwiftExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CFB9BA3A82D5F6FE7CCE5A5 /* libPods-SwiftExample.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -77,10 +77,10 @@
28D8326B1AEC177E009E3B3F /* ValidationExamplesFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationExamplesFormViewController.swift; sourceTree = "<group>"; };
28D8326E1AEC2D1B009E3B3F /* UICustomizationFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICustomizationFormViewController.swift; sourceTree = "<group>"; };
28F490211AAFBBC600C8E0CC /* DatesFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DatesFormViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
2EB9C638FC2450A0B9786D1E /* Pods-SwiftExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample.release.xcconfig"; sourceTree = "<group>"; };
420D9BAB7B0D2AF9487DD060 /* Pods-SwiftExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample.debug.xcconfig"; sourceTree = "<group>"; };
9CFB9BA3A82D5F6FE7CCE5A5 /* libPods-SwiftExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
BF01E92A1C21FF2800BDE045 /* InlineSegmentedCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InlineSegmentedCell.swift; path = InlineSegmentedCell/InlineSegmentedCell.swift; sourceTree = "<group>"; };
CD0A6F89B9CD5843CA297E52 /* Pods-SwiftExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample.release.xcconfig"; sourceTree = "<group>"; };
E006C7F7FF8E967AA8661BC9 /* libPods-SwiftExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F019783EE34BD17E2BA41467 /* Pods-SwiftExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -88,7 +88,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DD7B43598E698717584375E9 /* libPods-SwiftExample.a in Frameworks */,
649437BA8D5B7C59BBDB7B92 /* libPods-SwiftExample.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -100,8 +100,8 @@
children = (
2847A6A01AAF2679000A2ABE /* SwiftExample */,
2847A69F1AAF2679000A2ABE /* Products */,
7A12A831117D9B4D152E0A51 /* Pods */,
402AE3EC1FACD058DCF0A2D3 /* Frameworks */,
E9F3DD7ACEF5AAF92FCE6E24 /* Pods */,
3D93F92C6A8B49B82B452B67 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -324,23 +324,14 @@
path = SwiftExample/Dates;
sourceTree = SOURCE_ROOT;
};
402AE3EC1FACD058DCF0A2D3 /* Frameworks */ = {
3D93F92C6A8B49B82B452B67 /* Frameworks */ = {
isa = PBXGroup;
children = (
9CFB9BA3A82D5F6FE7CCE5A5 /* libPods-SwiftExample.a */,
E006C7F7FF8E967AA8661BC9 /* libPods-SwiftExample.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
7A12A831117D9B4D152E0A51 /* Pods */ = {
isa = PBXGroup;
children = (
420D9BAB7B0D2AF9487DD060 /* Pods-SwiftExample.debug.xcconfig */,
2EB9C638FC2450A0B9786D1E /* Pods-SwiftExample.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
BF01E9291C21FEF700BDE045 /* Inline Segmented */ = {
isa = PBXGroup;
children = (
@@ -349,6 +340,15 @@
name = "Inline Segmented";
sourceTree = "<group>";
};
E9F3DD7ACEF5AAF92FCE6E24 /* Pods */ = {
isa = PBXGroup;
children = (
F019783EE34BD17E2BA41467 /* Pods-SwiftExample.debug.xcconfig */,
CD0A6F89B9CD5843CA297E52 /* Pods-SwiftExample.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -356,12 +356,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 2847A6BD1AAF2679000A2ABE /* Build configuration list for PBXNativeTarget "SwiftExample" */;
buildPhases = (
21FCE00817B1AE1029F382A4 /* 📦 Check Pods Manifest.lock */,
89E8536C00EFF5D0377E1AE9 /* [CP] Check Pods Manifest.lock */,
2847A69A1AAF2679000A2ABE /* Sources */,
2847A69B1AAF2679000A2ABE /* Frameworks */,
2847A69C1AAF2679000A2ABE /* Resources */,
A0F2DA95250A4C3E69515D96 /* 📦 Copy Pods Resources */,
DCA1F7B1D7E04613B3E151C1 /* 📦 Embed Pods Frameworks */,
9BD9BF77E99A8DF4A44D2DB8 /* [CP] Embed Pods Frameworks */,
DC50100813F1902A0CFCE009 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -380,11 +380,12 @@
attributes = {
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = Xmartlabs;
TargetAttributes = {
2847A69D1AAF2679000A2ABE = {
CreatedOnToolsVersion = 6.2;
LastSwiftMigration = 0900;
};
};
};
@@ -422,44 +423,32 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
21FCE00817B1AE1029F382A4 /* 📦 Check Pods Manifest.lock */ = {
89E8536C00EFF5D0377E1AE9 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "📦 Check Pods Manifest.lock";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-SwiftExample-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
A0F2DA95250A4C3E69515D96 /* 📦 Copy Pods Resources */ = {
9BD9BF77E99A8DF4A44D2DB8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -467,6 +456,24 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
DC50100813F1902A0CFCE009 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample-resources.sh",
"${PODS_ROOT}/../../../XLForm/XLForm.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftExample/Pods-SwiftExample-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -515,13 +522,21 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -530,6 +545,7 @@
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -542,7 +558,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -559,13 +575,21 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -573,15 +597,17 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -589,7 +615,7 @@
};
2847A6BE1AAF2679000A2ABE /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 420D9BAB7B0D2AF9487DD060 /* Pods-SwiftExample.debug.xcconfig */;
baseConfigurationReference = F019783EE34BD17E2BA41467 /* Pods-SwiftExample.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -598,12 +624,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "SwiftExample/SwiftExample-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
2847A6BF1AAF2679000A2ABE /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2EB9C638FC2450A0B9786D1E /* Pods-SwiftExample.release.xcconfig */;
baseConfigurationReference = CD0A6F89B9CD5843CA297E52 /* Pods-SwiftExample.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@@ -612,6 +640,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "SwiftExample/SwiftExample-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@@ -28,7 +28,7 @@
class AccessoryViewFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let AccessoryViewRowNavigationEnabled = "RowNavigationEnabled"
static let AccessoryViewRowNavigationShowAccessoryView = "RowNavigationShowAccessoryView"
static let AccessoryViewRowNavigationStopDisableRow = "rowNavigationStopDisableRow"
@@ -44,7 +44,7 @@ class AccessoryViewFormViewController : XLFormViewController {
static let AccessoryViewNotes = "notes"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -61,7 +61,7 @@ class AccessoryViewFormViewController : XLFormViewController {
var row : XLFormRowDescriptor
form = XLFormDescriptor(title: "Accessory View")
form.rowNavigationOptions = .Enabled
form.rowNavigationOptions = .enabled
// Configuration section
section = XLFormSectionDescriptor()
@@ -76,25 +76,25 @@ class AccessoryViewFormViewController : XLFormViewController {
// RowNavigationShowAccessoryView
row = XLFormRowDescriptor(tag: Tags.AccessoryViewRowNavigationShowAccessoryView, rowType:XLFormRowDescriptorTypeBooleanCheck, title:"Show input accessory row?")
row.value = form.rowNavigationOptions.contains(.Enabled)
row.value = form.rowNavigationOptions.contains(.enabled)
row.hidden = "$\(Tags.AccessoryViewRowNavigationEnabled) == 0"
section.addFormRow(row)
// RowNavigationStopDisableRow
row = XLFormRowDescriptor(tag: Tags.AccessoryViewRowNavigationStopDisableRow, rowType: XLFormRowDescriptorTypeBooleanCheck, title:"Stop when reach disabled row?")
row.value = form.rowNavigationOptions.contains(.StopDisableRow)
row.value = form.rowNavigationOptions.contains(.stopDisableRow)
row.hidden = "$\(Tags.AccessoryViewRowNavigationEnabled) == 0"
section.addFormRow(row)
// RowNavigationStopInlineRow
row = XLFormRowDescriptor(tag: Tags.AccessoryViewRowNavigationStopInlineRow, rowType: XLFormRowDescriptorTypeBooleanCheck, title: "Stop when reach inline row?")
row.value = form.rowNavigationOptions.contains(.StopInlineRow)
row.value = form.rowNavigationOptions.contains(.stopInlineRow)
row.hidden = "$\(Tags.AccessoryViewRowNavigationEnabled) == 0"
section.addFormRow(row)
// RowNavigationSkipCanNotBecomeFirstResponderRow
row = XLFormRowDescriptor(tag: Tags.AccessoryViewRowNavigationSkipCanNotBecomeFirstResponderRow, rowType:XLFormRowDescriptorTypeBooleanCheck, title:"Skip Can Not Become First Responder Row?")
row.value = form.rowNavigationOptions.contains(XLFormRowNavigationOptions.SkipCanNotBecomeFirstResponderRow)
row.value = form.rowNavigationOptions.contains(XLFormRowNavigationOptions.skipCanNotBecomeFirstResponderRow)
row.hidden = "$\(Tags.AccessoryViewRowNavigationEnabled) == 0"
section.addFormRow(row)
@@ -103,18 +103,18 @@ class AccessoryViewFormViewController : XLFormViewController {
// Name
row = XLFormRowDescriptor(tag: Tags.AccessoryViewName, rowType: XLFormRowDescriptorTypeText, title: "Name")
row.required = true
row.isRequired = true
section.addFormRow(row)
// Email
row = XLFormRowDescriptor(tag: Tags.AccessoryViewEmail, rowType: XLFormRowDescriptorTypeEmail, title: "Email")
// validate the email
row.addValidator(XLFormValidator.emailValidator())
row.addValidator(XLFormValidator.email())
section.addFormRow(row)
// Twitter
row = XLFormRowDescriptor(tag: Tags.AccessoryViewTwitter, rowType: XLFormRowDescriptorTypeTwitter, title: "Twitter")
row.disabled = NSNumber(bool: true)
row.disabled = NSNumber(value: true as Bool)
row.value = "@no_editable"
section.addFormRow(row)
@@ -125,7 +125,7 @@ class AccessoryViewFormViewController : XLFormViewController {
// Date
row = XLFormRowDescriptor(tag: Tags.AccessoryViewDate, rowType:XLFormRowDescriptorTypeDateInline, title:"Date Inline")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
@@ -152,43 +152,43 @@ class AccessoryViewFormViewController : XLFormViewController {
}
override func inputAccessoryViewForRowDescriptor(rowDescriptor: XLFormRowDescriptor!) -> UIView! {
if form.formRowWithTag(Tags.AccessoryViewRowNavigationShowAccessoryView)!.value!.boolValue == false {
override func inputAccessoryView(for rowDescriptor: XLFormRowDescriptor!) -> UIView! {
if (form.formRow(withTag: Tags.AccessoryViewRowNavigationShowAccessoryView)!.value! as AnyObject).boolValue == false {
return nil
}
return super.inputAccessoryViewForRowDescriptor(rowDescriptor)
return super.inputAccessoryView(for: rowDescriptor)
}
//MARK: XLFormDescriptorDelegate
override func formRowDescriptorValueHasChanged(formRow: XLFormRowDescriptor!, oldValue: AnyObject!, newValue: AnyObject!) {
override func formRowDescriptorValueHasChanged(_ formRow: XLFormRowDescriptor!, oldValue: Any!, newValue: Any!) {
super.formRowDescriptorValueHasChanged(formRow, oldValue: oldValue, newValue: newValue)
if formRow.tag == Tags.AccessoryViewRowNavigationStopDisableRow {
if formRow.value!.boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.StopDisableRow)
if (formRow.value! as AnyObject).boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.stopDisableRow)
}
else{
form.rowNavigationOptions = form.rowNavigationOptions.subtract(.StopDisableRow)
form.rowNavigationOptions = form.rowNavigationOptions.subtracting(.stopDisableRow)
}
}
else if formRow.tag == Tags.AccessoryViewRowNavigationStopInlineRow {
if formRow.value!.boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.StopInlineRow)
if (formRow.value! as AnyObject).boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.stopInlineRow)
}
else{
var options = form.rowNavigationOptions
options = options.subtract(XLFormRowNavigationOptions.StopInlineRow)
options = options.subtracting(XLFormRowNavigationOptions.stopInlineRow)
form.rowNavigationOptions = options
}
}
else if formRow.tag == Tags.AccessoryViewRowNavigationSkipCanNotBecomeFirstResponderRow {
if formRow.value!.boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.SkipCanNotBecomeFirstResponderRow)
if (formRow.value! as AnyObject).boolValue == true {
form.rowNavigationOptions = form.rowNavigationOptions.union(.skipCanNotBecomeFirstResponderRow)
}
else{
var options = form.rowNavigationOptions
options = options.subtract(.SkipCanNotBecomeFirstResponderRow)
options = options.subtracting(.skipCanNotBecomeFirstResponderRow)
form.rowNavigationOptions = options
}
}
+10 -10
View File
@@ -14,20 +14,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Declare custom rows
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeRate] = "XLFormRatingCell"
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeRate] = NSStringFromClass(XLFormRatingCell.self)
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeFloatLabeledTextField] = FloatLabeledTextFieldCell.self
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeWeekDays] = "XLFormWeekDaysCell"
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeWeekDays] = NSStringFromClass(XLFormWeekDaysCell.self)
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeSegmentedInline] = InlineSegmentedCell.self
XLFormViewController.cellClassesForRowDescriptorTypes()[XLFormRowDescriptorTypeSegmentedControl] = InlineSegmentedControl.self
XLFormViewController.inlineRowDescriptorTypesForRowDescriptorTypes()[XLFormRowDescriptorTypeSegmentedInline] = XLFormRowDescriptorTypeSegmentedControl
// Override point for customization after application launch.
self.window = UIWindow.init(frame: UIScreen.mainScreen().bounds)
self.window = UIWindow.init(frame: UIScreen.main.bounds)
// Override point for customization after application launch.
self.window!.backgroundColor = .whiteColor()
self.window!.backgroundColor = .white
// load the initial form form Storybiard
let storyboard = UIStoryboard.init(name:"iPhoneStoryboard", bundle:nil)
@@ -36,25 +36,25 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@@ -24,7 +24,7 @@
class CustomRowsViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let CustomRowFirstRatingTag = "CustomRowFirstRatingTag"
static let CustomRowSecondRatingTag = "CustomRowSecondRatingTag"
static let CustomRowFloatLabeledTextFieldTag = "CustomRowFloatLabeledTextFieldTag"
@@ -33,7 +33,7 @@ class CustomRowsViewController : XLFormViewController {
static let CustomRowInline = "CustomRowInline"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
@@ -64,7 +64,7 @@ class CustomRowsViewController : XLFormViewController {
section.addFormRow(row)
// Section Float Labeled Text Field
section = XLFormSectionDescriptor.formSectionWithTitle("Float Labeled Text Field")
section = XLFormSectionDescriptor.formSection(withTitle: "Float Labeled Text Field")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.CustomRowFloatLabeledTextFieldTag, rowType: XLFormRowDescriptorTypeFloatLabeledTextField, title: "Title")
@@ -77,23 +77,23 @@ class CustomRowsViewController : XLFormViewController {
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Weekdays")
section = XLFormSectionDescriptor.formSection(withTitle: "Weekdays")
form.addFormSection(section)
// WeekDays
row = XLFormRowDescriptor(tag: Tags.CustomRowWeekdays, rowType: XLFormRowDescriptorTypeWeekDays)
row.value = [
XLFormWeekDaysCell.kWeekDay.Sunday.description(): false,
XLFormWeekDaysCell.kWeekDay.Monday.description(): true,
XLFormWeekDaysCell.kWeekDay.Tuesday.description(): true,
XLFormWeekDaysCell.kWeekDay.Wednesday.description(): false,
XLFormWeekDaysCell.kWeekDay.Thursday.description(): false,
XLFormWeekDaysCell.kWeekDay.Friday.description(): false,
XLFormWeekDaysCell.kWeekDay.Saturday.description(): false
XLFormWeekDaysCell.kWeekDay.sunday.description(): false,
XLFormWeekDaysCell.kWeekDay.monday.description(): true,
XLFormWeekDaysCell.kWeekDay.tuesday.description(): true,
XLFormWeekDaysCell.kWeekDay.wednesday.description(): false,
XLFormWeekDaysCell.kWeekDay.thursday.description(): false,
XLFormWeekDaysCell.kWeekDay.friday.description(): false,
XLFormWeekDaysCell.kWeekDay.saturday.description(): false
]
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Custom inline row")
section = XLFormSectionDescriptor.formSection(withTitle: "Custom inline row")
form.addFormSection(section)
// Inline
@@ -35,9 +35,9 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
lazy var floatLabeledTextField: JVFloatLabeledTextField = {
let result = JVFloatLabeledTextField(frame: CGRect.zero)
result.translatesAutoresizingMaskIntoConstraints = false
result.font = UIFont.systemFontOfSize(kFontSize)
result.floatingLabel.font = .boldSystemFontOfSize(kFontSize)
result.clearButtonMode = .WhileEditing
result.font = UIFont.systemFont(ofSize: FloatLabeledTextFieldCell.kFontSize)
result.floatingLabel.font = .boldSystemFont(ofSize: FloatLabeledTextFieldCell.kFontSize)
result.clearButtonMode = .whileEditing
return result
}()
@@ -45,7 +45,7 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
override func configure() {
super.configure()
selectionStyle = .None
selectionStyle = .none
contentView.addSubview(self.floatLabeledTextField)
floatLabeledTextField.delegate = self
contentView.addConstraints(layoutConstraints())
@@ -54,15 +54,15 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
override func update() {
super.update()
if let rowDescriptor = rowDescriptor {
floatLabeledTextField.attributedPlaceholder = NSAttributedString(string: rowDescriptor.title ?? "" , attributes: [NSForegroundColorAttributeName: UIColor.lightGrayColor()])
floatLabeledTextField.attributedPlaceholder = NSAttributedString(string: rowDescriptor.title ?? "" , attributes: [NSAttributedStringKey.foregroundColor: UIColor.lightGray])
if let value = rowDescriptor.value {
floatLabeledTextField.text = value.displayText()
floatLabeledTextField.text = (value as AnyObject).displayText()
}
else {
floatLabeledTextField.text = rowDescriptor.noValueDisplayText
}
floatLabeledTextField.enabled = !rowDescriptor.isDisabled()
floatLabeledTextField.floatingLabelTextColor = .lightGrayColor()
floatLabeledTextField.isEnabled = !rowDescriptor.isDisabled()
floatLabeledTextField.floatingLabelTextColor = .lightGray
floatLabeledTextField.alpha = rowDescriptor.isDisabled() ? 0.6 : 1.0
}
}
@@ -76,7 +76,7 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
return self.floatLabeledTextField.becomeFirstResponder()
}
override static func formDescriptorCellHeightForRowDescriptor(rowDescriptor: XLFormRowDescriptor!) -> CGFloat {
override static func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat {
return 55.0
}
@@ -86,12 +86,12 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
func layoutConstraints() -> [NSLayoutConstraint]{
let views = ["floatLabeledTextField" : floatLabeledTextField]
let metrics = ["hMargin": 15.0, "vMargin": 8.0]
var result = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(hMargin)-[floatLabeledTextField]-(hMargin)-|", options:.AlignAllCenterY, metrics:metrics, views:views)
result += NSLayoutConstraint.constraintsWithVisualFormat("V:|-(vMargin)-[floatLabeledTextField]-(vMargin)-|", options:.AlignAllCenterX, metrics:metrics, views:views)
var result = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(hMargin)-[floatLabeledTextField]-(hMargin)-|", options:.alignAllCenterY, metrics:metrics, views:views)
result += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(vMargin)-[floatLabeledTextField]-(vMargin)-|", options:.alignAllCenterX, metrics:metrics, views:views)
return result
}
func textFieldDidChange(textField : UITextField) {
func textFieldDidChange(_ textField : UITextField) {
if floatLabeledTextField == textField {
if let rowDescriptor = rowDescriptor, let text = self.floatLabeledTextField.text {
if text.isEmpty == false {
@@ -105,34 +105,34 @@ class FloatLabeledTextFieldCell : XLFormBaseCell, UITextFieldDelegate {
//Mark: UITextFieldDelegate
func textFieldShouldClear(textField: UITextField) -> Bool {
func textFieldShouldClear(_ textField: UITextField) -> Bool {
return self.formViewController().textFieldShouldClear(textField)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return self.formViewController().textFieldShouldReturn(textField)
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return self.formViewController().textFieldShouldBeginEditing(textField)
}
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
return self.formViewController().textFieldShouldEndEditing(textField)
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return self.formViewController().textField(textField, shouldChangeCharactersInRange: range, replacementString: string)
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return self.formViewController().textField(textField, shouldChangeCharactersIn: range, replacementString: string)
}
func textFieldDidBeginEditing(textField: UITextField) {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.formViewController().textFieldDidBeginEditing(textField)
}
func textFieldDidEndEditing(textField: UITextField) {
func textFieldDidEndEditing(_ textField: UITextField) {
self.textFieldDidChange(textField)
self.formViewController().textFieldDidEndEditing(textField)
}
@@ -14,18 +14,18 @@ let XLFormRowDescriptorTypeSegmentedControl = "XLFormRowDescriptorTypeSegmentedC
class InlineSegmentedCell : XLFormBaseCell {
override func canBecomeFirstResponder() -> Bool {
override var canBecomeFirstResponder : Bool {
return true
}
override func becomeFirstResponder() -> Bool {
if isFirstResponder() {
if isFirstResponder {
return super.becomeFirstResponder()
}
let result = super.becomeFirstResponder()
if result {
let inlineRowDescriptor : XLFormRowDescriptor = XLFormRowDescriptor(tag: nil, rowType: XLFormViewController.inlineRowDescriptorTypesForRowDescriptorTypes()![rowDescriptor!.rowType] as! String)
let cell = inlineRowDescriptor.cellForFormController(formViewController())
let cell = inlineRowDescriptor.cell(forForm: formViewController())
let inlineCell = cell as? XLFormInlineRowDescriptorCell
inlineCell?.inlineRowDescriptor = rowDescriptor
rowDescriptor?.sectionDescriptor.addFormRow(inlineRowDescriptor, afterRow: rowDescriptor!)
@@ -35,13 +35,13 @@ class InlineSegmentedCell : XLFormBaseCell {
}
override func resignFirstResponder() -> Bool {
if isFirstResponder() {
if !isFirstResponder {
return super.resignFirstResponder()
}
let selectedRowPath : NSIndexPath = formViewController().form.indexPathOfFormRow(rowDescriptor!)!
let nextRowPath = NSIndexPath(forRow: selectedRowPath.row + 1, inSection: selectedRowPath.section)
let nextFormRow = formViewController().form.formRowAtIndex(nextRowPath)
let section : XLFormSectionDescriptor = formViewController().form.formSectionAtIndex(UInt(nextRowPath.section))!
let selectedRowPath : IndexPath = formViewController().form.indexPath(ofFormRow: rowDescriptor!)!
let nextRowPath = IndexPath(row: (selectedRowPath as NSIndexPath).row + 1, section: (selectedRowPath as NSIndexPath).section)
let nextFormRow = formViewController().form.formRow(atIndex: nextRowPath)
let section : XLFormSectionDescriptor = formViewController().form.formSection(at: UInt((nextRowPath as NSIndexPath).section))!
let result = super.resignFirstResponder()
if result {
section.removeFormRow(nextFormRow!)
@@ -56,8 +56,8 @@ class InlineSegmentedCell : XLFormBaseCell {
}
override func formDescriptorCellBecomeFirstResponder() -> Bool {
if isFirstResponder() {
resignFirstResponder()
if isFirstResponder {
_ = resignFirstResponder()
return false
}
return becomeFirstResponder()
@@ -65,20 +65,20 @@ class InlineSegmentedCell : XLFormBaseCell {
override func update() {
super.update()
accessoryType = .None
editingAccessoryType = .None
selectionStyle = .None
accessoryType = .none
editingAccessoryType = .none
selectionStyle = .none
textLabel?.text = rowDescriptor?.title
detailTextLabel?.text = valueDisplayText()
}
override func formDescriptorCellDidSelectedWithFormController(controller: XLFormViewController!) {
controller.tableView.deselectRowAtIndexPath(controller.form.indexPathOfFormRow(rowDescriptor!)!, animated: true)
override func formDescriptorCellDidSelected(withForm controller: XLFormViewController!) {
controller.tableView.deselectRow(at: controller.form.indexPath(ofFormRow: rowDescriptor!)!, animated: true)
}
func valueDisplayText() -> String? {
if let value = rowDescriptor?.value {
return value.displayText()
return (value as AnyObject).displayText()
}
return rowDescriptor?.noValueDisplayText
}
@@ -93,22 +93,22 @@ class InlineSegmentedControl : XLFormBaseCell, XLFormInlineRowDescriptorCell {
override func configure() {
super.configure()
selectionStyle = .None
selectionStyle = .none
contentView.addSubview(segmentedControl)
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[segmentedControl]-|", options: .AlignAllCenterY, metrics: nil, views: ["segmentedControl": segmentedControl]))
segmentedControl.addTarget(self, action: "valueChanged", forControlEvents: .ValueChanged)
contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[segmentedControl]-|", options: .alignAllCenterY, metrics: nil, views: ["segmentedControl": segmentedControl]))
segmentedControl.addTarget(self, action: #selector(InlineSegmentedControl.valueChanged), for: .valueChanged)
}
override func update() {
super.update()
updateSegmentedControl()
segmentedControl.selectedSegmentIndex = selectedIndex()
segmentedControl.enabled = rowDescriptor?.isDisabled() == false
segmentedControl.isEnabled = rowDescriptor?.isDisabled() == false
}
//MARK: Actions
func valueChanged() {
@objc func valueChanged() {
inlineRowDescriptor!.value = inlineRowDescriptor!.selectorOptions![segmentedControl.selectedSegmentIndex]
formViewController().updateFormRow(inlineRowDescriptor)
}
@@ -118,27 +118,27 @@ class InlineSegmentedControl : XLFormBaseCell, XLFormInlineRowDescriptorCell {
func getItems() -> NSMutableArray {
let result = NSMutableArray()
for option in inlineRowDescriptor!.selectorOptions! {
result.addObject(option.displayText())
result.add((option as AnyObject).displayText())
}
return result
}
func updateSegmentedControl() {
segmentedControl.removeAllSegments()
getItems().enumerateObjectsUsingBlock { [weak self] object, index, stop in
self?.segmentedControl.insertSegmentWithTitle(object.displayText(), atIndex: index, animated: false)
}
getItems().enumerateObjects({ [weak self] (object, index, stop) in
self?.segmentedControl.insertSegment(withTitle: (object as AnyObject).displayText(), at: index, animated: false)
})
}
func selectedIndex() -> Int {
let formRow = inlineRowDescriptor ?? rowDescriptor
if let value = formRow?.value {
if let value = formRow?.value as? NSObject {
for option in (formRow?.selectorOptions)! {
if option.valueData().isEqual(value.valueData()){
return formRow?.selectorOptions?.indexOf({ $0.isEqual(option) }) ?? -1
if ((option as! NSObject).valueData() as AnyObject) === (value.valueData() as AnyObject) {
return formRow?.selectorOptions?.index(where: { ($0 as! NSObject) == (option as! NSObject) } ) ?? -1
}
}
}
return -1
}
}
}
@@ -39,7 +39,7 @@ class XLRatingView : AXRatingView {
func customize() {
baseColor = UIColor(red: (205/255.0), green: (201/255.0), blue: (201/255.0), alpha: 1)
highlightColor = UIColor(red: (255/255.0), green: (215/255.0), blue: 0, alpha: 1)
markFont = UIFont.systemFontOfSize(23.0)
markFont = UIFont.systemFont(ofSize: 23.0)
stepInterval = 1.0
}
@@ -34,14 +34,14 @@ class XLFormRatingCell : XLFormBaseCell {
override func configure() {
super.configure()
selectionStyle = .None
ratingView.addTarget(self, action: "rateChanged:", forControlEvents:.ValueChanged)
selectionStyle = .none
ratingView.addTarget(self, action: #selector(XLFormRatingCell.rateChanged(_:)), for:.valueChanged)
}
override func update() {
super.update()
ratingView.value = rowDescriptor!.value!.floatValue
ratingView.value = (rowDescriptor!.value! as AnyObject).floatValue
rateTitle.text = rowDescriptor!.title
ratingView.alpha = rowDescriptor!.isDisabled() ? 0.6 : 1
rateTitle.alpha = rowDescriptor!.isDisabled() ? 0.6 : 1
@@ -49,7 +49,7 @@ class XLFormRatingCell : XLFormBaseCell {
//MARK: Events
func rateChanged(ratingView : XLRatingView){
@objc func rateChanged(_ ratingView : XLRatingView){
rowDescriptor!.value = ratingView.value
}
@@ -30,29 +30,29 @@ class XLFormWeekDaysCell : XLFormBaseCell {
enum kWeekDay: Int {
case
Sunday = 1,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
sunday = 1,
monday,
tuesday,
wednesday,
thursday,
friday,
saturday
func description() -> String {
switch self {
case .Sunday:
case .sunday:
return "Sunday"
case .Monday:
case .monday:
return "Monday"
case .Tuesday:
case .tuesday:
return "Tuesday"
case .Wednesday:
case .wednesday:
return "Wednesday"
case .Thursday:
case .thursday:
return "Thursday"
case .Friday:
case .friday:
return "Friday"
case .Saturday:
case .saturday:
return "Saturday"
}
}
@@ -60,13 +60,13 @@ class XLFormWeekDaysCell : XLFormBaseCell {
//Add Custom Functions
//Allows for iteration as needed (for in ...)
static let allValues = [Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday]
static let allValues = [sunday,
monday,
tuesday,
wednesday,
thursday,
friday,
saturday]
}
@IBOutlet weak var sundayButton: UIButton!
@@ -81,7 +81,7 @@ class XLFormWeekDaysCell : XLFormBaseCell {
override func configure() {
super.configure()
selectionStyle = .None
selectionStyle = .none
configureButtons()
}
@@ -91,17 +91,17 @@ class XLFormWeekDaysCell : XLFormBaseCell {
updateButtons()
}
override static func formDescriptorCellHeightForRowDescriptor(rowDescriptor: XLFormRowDescriptor!) -> CGFloat {
override static func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat {
return 60
}
//MARK: - Action
@IBAction func dayTapped(sender: UIButton) {
@IBAction func dayTapped(_ sender: UIButton) {
let day = getDayFormButton(sender)
sender.selected = !sender.selected
sender.isSelected = !sender.isSelected
var newValue = rowDescriptor!.value as! Dictionary<String, Bool>
newValue[day] = sender.selected
newValue[day] = sender.isSelected
rowDescriptor!.value = newValue
}
@@ -110,8 +110,8 @@ class XLFormWeekDaysCell : XLFormBaseCell {
func configureButtons() {
for subview in contentView.subviews {
if let button = subview as? UIButton {
button.setImage(UIImage(named: "uncheckedDay"), forState: .Normal)
button.setImage(UIImage(named: "checkedDay"), forState: .Selected)
button.setImage(UIImage(named: "uncheckedDay"), for: UIControlState())
button.setImage(UIImage(named: "checkedDay"), for: .selected)
button.adjustsImageWhenHighlighted = false
imageTopTitleBottom(button)
}
@@ -122,13 +122,13 @@ class XLFormWeekDaysCell : XLFormBaseCell {
func updateButtons() {
var value = rowDescriptor!.value as! Dictionary<String, Bool>
sundayButton.selected = value[kWeekDay.Sunday.description()]!
mondayButton.selected = value[kWeekDay.Monday.description()]!
tuesdayButton.selected = value[kWeekDay.Tuesday.description()]!
wednesdayButton.selected = value[kWeekDay.Wednesday.description()]!
thursdayButton.selected = value[kWeekDay.Thursday.description()]!
fridayButton.selected = value[kWeekDay.Friday.description()]!
saturdayButton.selected = value[kWeekDay.Saturday.description()]!
sundayButton.isSelected = value[kWeekDay.sunday.description()]!
mondayButton.isSelected = value[kWeekDay.monday.description()]!
tuesdayButton.isSelected = value[kWeekDay.tuesday.description()]!
wednesdayButton.isSelected = value[kWeekDay.wednesday.description()]!
thursdayButton.isSelected = value[kWeekDay.thursday.description()]!
fridayButton.isSelected = value[kWeekDay.friday.description()]!
saturdayButton.isSelected = value[kWeekDay.saturday.description()]!
sundayButton.alpha = rowDescriptor!.isDisabled() ? 0.6 : 1
mondayButton.alpha = mondayButton.alpha
@@ -139,7 +139,7 @@ class XLFormWeekDaysCell : XLFormBaseCell {
saturdayButton.alpha = mondayButton.alpha
}
func imageTopTitleBottom(button: UIButton) {
func imageTopTitleBottom(_ button: UIButton) {
// the space between the image and text
let spacing : CGFloat = 3.0
@@ -150,26 +150,26 @@ class XLFormWeekDaysCell : XLFormBaseCell {
// raise the image and push it right so it appears centered
// above the text
let titleSize : CGSize = (button.titleLabel!.text! as NSString).sizeWithAttributes([NSFontAttributeName: button.titleLabel!.font])
let titleSize : CGSize = (button.titleLabel!.text! as NSString).size(withAttributes: [NSAttributedStringKey.font: button.titleLabel!.font])
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0.0, 0.0, -titleSize.width)
}
func getDayFormButton(button: UIButton) -> String {
func getDayFormButton(_ button: UIButton) -> String {
switch button {
case sundayButton:
return kWeekDay.Sunday.description()
return kWeekDay.sunday.description()
case mondayButton:
return kWeekDay.Monday.description()
return kWeekDay.monday.description()
case tuesdayButton:
return kWeekDay.Tuesday.description()
return kWeekDay.tuesday.description()
case wednesdayButton:
return kWeekDay.Wednesday.description()
return kWeekDay.wednesday.description()
case thursdayButton:
return kWeekDay.Thursday.description()
return kWeekDay.thursday.description()
case fridayButton:
return kWeekDay.Friday.description()
return kWeekDay.friday.description()
default:
return kWeekDay.Saturday.description()
return kWeekDay.saturday.description()
}
}
@@ -28,12 +28,12 @@ import MapKit
class CustomSelectorsFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let SelectorMap = "selectorMap"
static let SelectorMapPopover = "selectorMapPopover"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -51,7 +51,7 @@ class CustomSelectorsFormViewController : XLFormViewController {
form = XLFormDescriptor(title: "Custom Selectors")
section = XLFormSectionDescriptor.formSectionWithTitle("TextField Types")
section = XLFormSectionDescriptor.formSection(withTitle: "TextField Types")
section.footerTitle = "CustomSelectorsFormViewController.swift"
form.addFormSection(section)
@@ -62,7 +62,7 @@ class CustomSelectorsFormViewController : XLFormViewController {
row.value = CLLocation(latitude: -33, longitude: -56)
section.addFormRow(row)
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
if UIDevice.current.userInterfaceIdiom == .pad {
// Selector PopOver
row = XLFormRowDescriptor(tag: Tags.SelectorMapPopover, rowType: XLFormRowDescriptorTypeSelectorPopover, title: "Coordinate PopOver")
row.action.viewControllerClass = MapViewController.self
@@ -26,7 +26,7 @@
import MapKit
class CLLocationValueTrasformer : NSValueTransformer {
class CLLocationValueTrasformer : ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return NSString.self
@@ -37,7 +37,7 @@ class CLLocationValueTrasformer : NSValueTransformer {
return false
}
override func transformedValue(value: AnyObject?) -> AnyObject? {
override func transformedValue(_ value: Any?) -> Any? {
if let valueData = value, let location = valueData as? CLLocation{
return String(format: "%0.4f, %0.4f", location.coordinate.latitude, location.coordinate.longitude)
}
@@ -42,11 +42,11 @@ class MapViewController : UIViewController, XLFormRowDescriptorViewController, M
var rowDescriptor: XLFormRowDescriptor?
lazy var mapView : MKMapView = { [unowned self] in
let mapView = MKMapView(frame: self.view.frame)
mapView.autoresizingMask = [UIViewAutoresizing.FlexibleHeight, UIViewAutoresizing.FlexibleWidth]
mapView.autoresizingMask = [UIViewAutoresizing.flexibleHeight, UIViewAutoresizing.flexibleWidth]
return mapView
}()
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
@@ -60,7 +60,7 @@ class MapViewController : UIViewController, XLFormRowDescriptorViewController, M
view.addSubview(mapView)
mapView.delegate = self
if let value = rowDescriptor?.value as? CLLocation {
mapView.setCenterCoordinate(value.coordinate, animated: false)
mapView.setCenter(value.coordinate, animated: false)
title = String(format: "%0.4f, %0.4f", mapView.centerCoordinate.latitude, mapView.centerCoordinate.longitude)
let annotation = MapAnnotation()
annotation.coordinate = value.coordinate
@@ -70,18 +70,18 @@ class MapViewController : UIViewController, XLFormRowDescriptorViewController, M
//MARK - - MKMapViewDelegate
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "annotation")
pinAnnotationView.pinColor = MKPinAnnotationColor.Red
pinAnnotationView.draggable = true
pinAnnotationView.pinColor = MKPinAnnotationColor.red
pinAnnotationView.isDraggable = true
pinAnnotationView.animatesDrop = true
return pinAnnotationView
}
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == .Ending){
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if (newState == .ending){
if let rowDescriptor = rowDescriptor, let annotation = view.annotation {
rowDescriptor.value = CLLocation(latitude:annotation.coordinate.latitude, longitude:annotation.coordinate.longitude)
self.title = String(format: "%0.4f, %0.4f", annotation.coordinate.latitude, annotation.coordinate.longitude)
@@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
class DateValueTrasformer : NSValueTransformer {
class DateValueTrasformer : ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return NSString.self
@@ -34,18 +34,18 @@ class DateValueTrasformer : NSValueTransformer {
return false
}
override func transformedValue(value: AnyObject?) -> AnyObject? {
if let date = value as? NSDate {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .FullStyle
dateFormatter.timeStyle = .NoStyle
return dateFormatter.stringFromDate(date)
override func transformedValue(_ value: Any?) -> Any? {
if let date = value as? Date {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .none
return dateFormatter.string(from: date)
}
return nil
}
}
class DateTimeValueTrasformer: NSValueTransformer {
class DateTimeValueTrasformer: ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return NSString.self
@@ -56,12 +56,12 @@ class DateTimeValueTrasformer: NSValueTransformer {
return false
}
override func transformedValue(value: AnyObject?) -> AnyObject? {
if let date = value as? NSDate {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateFormatter.timeStyle = .ShortStyle
return dateFormatter.stringFromDate(date)
override func transformedValue(_ value: Any?) -> Any? {
if let date = value as? Date {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
return dateFormatter.string(from: date)
}
return nil
}
@@ -26,7 +26,7 @@
class DatesFormViewController: XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let DateInline = "dateInline"
static let TimeInline = "timeInline"
static let DateTimeInline = "dateTimeInline"
@@ -38,7 +38,7 @@ class DatesFormViewController: XLFormViewController {
static let CountDownTimer = "countDownTimer"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -50,15 +50,15 @@ class DatesFormViewController: XLFormViewController {
override func viewDidLoad() {
super.viewDidLoad()
let barButton = UIBarButtonItem(title: "Disable", style: .Plain, target: self, action: "disableEnable:")
let barButton = UIBarButtonItem(title: "Disable", style: .plain, target: self, action: #selector(DatesFormViewController.disableEnable(_:)))
barButton.possibleTitles = Set(["Disable", "Enable"])
navigationItem.rightBarButtonItem = barButton
}
func disableEnable(button : UIBarButtonItem){
form.disabled = !form.disabled
button.title = form.disabled ? "Enable" : "Disable"
@objc func disableEnable(_ button : UIBarButtonItem){
form.isDisabled = !form.isDisabled
button.title = form.isDisabled ? "Enable" : "Disable"
tableView.endEditing(true)
tableView.reloadData()
}
@@ -70,78 +70,79 @@ class DatesFormViewController: XLFormViewController {
form = XLFormDescriptor(title: "Date & Time")
section = XLFormSectionDescriptor.formSectionWithTitle("Inline Dates")
section = XLFormSectionDescriptor.formSection(withTitle: "Inline Dates")
form.addFormSection(section)
// Date
row = XLFormRowDescriptor(tag: Tags.DateInline, rowType: XLFormRowDescriptorTypeDateInline, title:"Date")
row.value = NSDate()
row.value = Date()
row.cellConfigAtConfigure["locale"] = Locale(identifier: "FR_fr")
section.addFormRow(row)
// Time
row = XLFormRowDescriptor(tag: Tags.TimeInline, rowType: XLFormRowDescriptorTypeTimeInline, title: "Time")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
// DateTime
row = XLFormRowDescriptor(tag: Tags.DateTimeInline, rowType: XLFormRowDescriptorTypeDateTimeInline, title: "Date Time")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
// CountDownTimer
row = XLFormRowDescriptor(tag: Tags.CountDownTimerInline, rowType:XLFormRowDescriptorTypeCountDownTimerInline, title:"Countdown Timer")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Dates") //
section = XLFormSectionDescriptor.formSection(withTitle: "Dates") //
form.addFormSection(section)
// Date
row = XLFormRowDescriptor(tag: Tags.Date, rowType:XLFormRowDescriptorTypeDate, title:"Date")
row.value = NSDate()
row.cellConfigAtConfigure["minimumDate"] = NSDate()
row.cellConfigAtConfigure["maximumDate"] = NSDate(timeIntervalSinceNow: 60*60*24*3)
row.value = Date()
row.cellConfigAtConfigure["minimumDate"] = Date()
row.cellConfigAtConfigure["maximumDate"] = Date(timeIntervalSinceNow: 60*60*24*3)
section.addFormRow(row)
// Time
row = XLFormRowDescriptor(tag: Tags.Time, rowType: XLFormRowDescriptorTypeTime, title: "Time")
row.cellConfigAtConfigure["minuteInterval"] = 10
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
// DateTime
row = XLFormRowDescriptor(tag: Tags.DateTime, rowType: XLFormRowDescriptorTypeDateTime, title: "Date Time")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
// CountDownTimer
row = XLFormRowDescriptor(tag: Tags.CountDownTimer, rowType: XLFormRowDescriptorTypeCountDownTimer, title: "Countdown Timer")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Disabled Dates")
section = XLFormSectionDescriptor.formSection(withTitle: "Disabled Dates")
section.footerTitle = "DatesFormViewController.swift"
form.addFormSection(section)
// Date
row = XLFormRowDescriptor(tag: nil, rowType: XLFormRowDescriptorTypeDate, title: "Date")
row.disabled = NSNumber(bool: true)
row.required = true
row.value = NSDate()
row.disabled = NSNumber(value: true as Bool)
row.isRequired = true
row.value = Date()
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("DatePicker")
section = XLFormSectionDescriptor.formSection(withTitle: "DatePicker")
form.addFormSection(section)
// DatePicker
row = XLFormRowDescriptor(tag: Tags.DatePicker, rowType:XLFormRowDescriptorTypeDatePicker)
row.cellConfigAtConfigure["datePicker.datePickerMode"] = UIDatePickerMode.Date.rawValue
row.value = NSDate()
row.cellConfigAtConfigure["datePicker.datePickerMode"] = UIDatePickerMode.date.rawValue
row.value = Date()
section.addFormRow(row)
@@ -150,12 +151,13 @@ class DatesFormViewController: XLFormViewController {
// MARK: - XLFormDescriptorDelegate
override func formRowDescriptorValueHasChanged(formRow: XLFormRowDescriptor!, oldValue: AnyObject!, newValue: AnyObject!) {
override func formRowDescriptorValueHasChanged(_ formRow: XLFormRowDescriptor!, oldValue: Any!, newValue: Any!) {
super.formRowDescriptorValueHasChanged(formRow, oldValue: oldValue, newValue: newValue)
if formRow.tag == Tags.DatePicker {
let alertView = UIAlertView(title: "DatePicker", message: "Value Has changed!", delegate: self, cancelButtonTitle: "OK")
alertView.show()
let alert = UIAlertController(title: "DatePicker", message: "Values has changed!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
}
@@ -25,7 +25,7 @@
class DynamicSelectorsFormViewController : XLFormViewController {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -42,7 +42,7 @@ class DynamicSelectorsFormViewController : XLFormViewController {
var row : XLFormRowDescriptor
// Basic Information
section = XLFormSectionDescriptor.formSectionWithTitle("Dynamic Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Dynamic Selectors")
section.footerTitle = "DynamicSelectorsFormViewController.swift"
form.addFormSection(section)
@@ -51,7 +51,7 @@ class DynamicSelectorsFormViewController : XLFormViewController {
row.action.viewControllerClass = UsersTableViewController.self
section.addFormRow(row)
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
if UIDevice.current.userInterfaceIdiom == .pad {
// Selector PopOver
row = XLFormRowDescriptor(tag: "selectorUserPopover", rowType:XLFormRowDescriptorTypeSelectorPopover, title:"User Popover")
row.action.viewControllerClass = UsersTableViewController.self
@@ -38,7 +38,7 @@ class UserCell : UITableViewCell {
lazy var userName : UILabel = {
let tempUserName = UILabel()
tempUserName.translatesAutoresizingMaskIntoConstraints = false
tempUserName.font = UIFont.systemFontOfSize(15.0)
tempUserName.font = UIFont.systemFont(ofSize: 15.0)
return tempUserName
}()
@@ -55,7 +55,7 @@ class UserCell : UITableViewCell {
fatalError("init(coder:) has not been implemented")
}
override func setSelected(selected: Bool, animated: Bool) {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
@@ -63,11 +63,11 @@ class UserCell : UITableViewCell {
// MARK: - Layout Constraints
func layoutConstraints() -> [NSLayoutConstraint]{
let views = ["image": self.userImage, "name": self.userName ]
let views = ["image": self.userImage, "name": self.userName ] as [String : Any]
let metrics = [ "imgSize": 50.0, "margin": 12.0]
var result = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(margin)-[image(imgSize)]-[name]", options:.AlignAllTop, metrics: metrics, views: views)
result += NSLayoutConstraint.constraintsWithVisualFormat("V:|-(margin)-[image(imgSize)]", options:NSLayoutFormatOptions(), metrics:metrics, views: views)
var result = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(margin)-[image(imgSize)]-[name]", options:.alignAllTop, metrics: metrics, views: views)
result += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(margin)-[image(imgSize)]", options:NSLayoutFormatOptions(), metrics:metrics, views: views)
return result
}
@@ -91,9 +91,9 @@ class UsersJSONSerialization {
"{\"id\":4,\"name\":\"Montgomery Burns\",\"imageName\":\"Montgomery_Burns.png\"}," +
"{\"id\":5,\"name\":\"Ned Flanders\",\"imageName\":\"Ned_Flanders.png\"}," +
"{\"id\":6,\"name\":\"Otto Mann\",\"imageName\":\"Otto_Mann.png\"}]"
let jsonData = dataString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let jsonData = dataString.data(using: String.Encoding.utf8, allowLossyConversion: true)
do {
let result = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions()) as! Array<AnyObject>
let result = try JSONSerialization.jsonObject(with: jsonData!, options: JSONSerialization.ReadingOptions()) as! Array<AnyObject>
return result
}
catch let error as NSError {
@@ -124,29 +124,25 @@ class User: NSObject, XLFormOptionObject {
func formDisplayText() -> String {
return self.userName
}
func formValue() -> AnyObject {
return self.userId
func formValue() -> Any {
return self.userId as Any
}
}
class UsersTableViewController : UITableViewController, XLFormRowDescriptorViewController, XLFormRowDescriptorPopoverViewController {
class UsersTableViewController : UITableViewController, XLFormRowDescriptorViewController {
var rowDescriptor : XLFormRowDescriptor?
var popoverController : UIPopoverController?
var userCell : UserCell?
private let kUserCellIdentifier = "UserCell"
fileprivate let kUserCellIdentifier = "UserCell"
override init(style: UITableViewStyle) {
super.init(style: style);
}
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: Bundle!) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
@@ -156,53 +152,53 @@ class UsersTableViewController : UITableViewController, XLFormRowDescriptorViewC
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UserCell.self, forCellReuseIdentifier: kUserCellIdentifier)
tableView.register(UserCell.self, forCellReuseIdentifier: kUserCellIdentifier)
tableView.tableFooterView = UIView(frame: CGRect.zero)
}
// MARK: UITableViewDataSource
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return UsersJSONSerialization.sharedInstance.userData!.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UserCell = tableView.dequeueReusableCellWithIdentifier(self.kUserCellIdentifier, forIndexPath: indexPath) as! UserCell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UserCell = tableView.dequeueReusableCell(withIdentifier: self.kUserCellIdentifier, for: indexPath) as! UserCell
let usersData = UsersJSONSerialization.sharedInstance.userData! as! Array<Dictionary<String, AnyObject>>
let userData = usersData[indexPath.row] as Dictionary<String, AnyObject>
let userData = usersData[(indexPath as NSIndexPath).row] as Dictionary<String, AnyObject>
let userId = userData["id"] as! Int
cell.userName.text = userData["name"] as? String
cell.userImage.image = UIImage(named: (userData["imageName"] as? String)!)
if let value = rowDescriptor?.value {
cell.accessoryType = value.formValue().isEqual(userId) ? .Checkmark : .None
cell.accessoryType = ((value as? XLFormOptionObject)?.formValue() as? Int) == userId ? .checkmark : .none
}
return cell;
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 73.0
}
//MARK: UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let usersData = UsersJSONSerialization.sharedInstance.userData! as! Array<Dictionary<String, AnyObject>>
let userData = usersData[indexPath.row] as Dictionary<String, AnyObject>
let userData = usersData[(indexPath as NSIndexPath).row] as Dictionary<String, AnyObject>
let user = User(userId: (userData["id"] as! Int), userName: userData["name"] as! String, userImage: userData["imageName"] as! String)
self.rowDescriptor!.value = user;
if let porpOver = self.popoverController {
porpOver.dismissPopoverAnimated(true)
porpOver.delegate?.popoverControllerDidDismissPopover!(porpOver)
if let popOver = self.presentedViewController, popOver.modalPresentationStyle == .popover {
dismiss(animated: true, completion: nil)
}
else if parentViewController is UINavigationController {
navigationController?.popViewControllerAnimated(true)
else if parent is UINavigationController {
navigationController?.popViewController(animated: true)
}
}
@@ -28,7 +28,7 @@
class ExamplesFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let RealExample = "RealExamples"
static let TextFieldAndTextView = "TextFieldAndTextView"
static let Selectors = "Selectors"
@@ -46,7 +46,7 @@ class ExamplesFormViewController : XLFormViewController {
static let AccessoryView = "Accessory View"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -66,7 +66,7 @@ class ExamplesFormViewController : XLFormViewController {
form = XLFormDescriptor()
section = XLFormSectionDescriptor.formSectionWithTitle("Real examples")
section = XLFormSectionDescriptor.formSection(withTitle: "Real examples")
form.addFormSection(section)
// NativeEventFormViewController
@@ -74,7 +74,7 @@ class ExamplesFormViewController : XLFormViewController {
row.action.formSegueIdentifier = "NativeEventNavigationViewControllerSegue"
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("This form is actually an example")
section = XLFormSectionDescriptor.formSection(withTitle: "This form is actually an example")
section.footerTitle = "ExamplesFormViewController.swift, Select an option to view another example"
form.addFormSection(section)
@@ -102,7 +102,7 @@ class ExamplesFormViewController : XLFormViewController {
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Multivalued example")
section = XLFormSectionDescriptor.formSection(withTitle: "Multivalued example")
form.addFormSection(section)
@@ -123,14 +123,14 @@ class ExamplesFormViewController : XLFormViewController {
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("UI Customization")
section = XLFormSectionDescriptor.formSection(withTitle: "UI Customization")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.UICusomization, rowType: XLFormRowDescriptorTypeButton, title:"UI Customization")
row.action.viewControllerClass = UICustomizationFormViewController.self
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Custom Rows")
section = XLFormSectionDescriptor.formSection(withTitle: "Custom Rows")
form.addFormSection(section)
@@ -138,7 +138,7 @@ class ExamplesFormViewController : XLFormViewController {
row.action.viewControllerClass = CustomRowsViewController.self
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Accessory View")
section = XLFormSectionDescriptor.formSection(withTitle: "Accessory View")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.AccessoryView, rowType: XLFormRowDescriptorTypeButton, title:"Accessory Views")
@@ -146,7 +146,7 @@ class ExamplesFormViewController : XLFormViewController {
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Validation Examples")
section = XLFormSectionDescriptor.formSection(withTitle: "Validation Examples")
form.addFormSection(section)
@@ -154,7 +154,7 @@ class ExamplesFormViewController : XLFormViewController {
row.action.formSegueIdentifier = "ValidationExamplesFormViewControllerSegue"
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Using Predicates")
section = XLFormSectionDescriptor.formSection(withTitle: "Using Predicates")
form.addFormSection(section)
@@ -66,6 +66,11 @@
"idiom" : "ipad",
"filename" : "xl_appicon_152.png",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
}
],
"info" : {
@@ -26,7 +26,7 @@
class InputsFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let Name = "name"
static let Email = "email"
static let Twitter = "twitter"
@@ -41,7 +41,7 @@ class InputsFormViewController : XLFormViewController {
static let Notes = "notes"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -60,25 +60,25 @@ class InputsFormViewController : XLFormViewController {
form = XLFormDescriptor(title: "Text Fields")
form.assignFirstResponderOnShow = true
section = XLFormSectionDescriptor.formSectionWithTitle("TextField Types")
section = XLFormSectionDescriptor.formSection(withTitle: "TextField Types")
section.footerTitle = "This is a long text that will appear on section footer"
form.addFormSection(section)
// Name
row = XLFormRowDescriptor(tag: Tags.Name, rowType: XLFormRowDescriptorTypeText, title: "Name")
row.required = true
row.isRequired = true
section.addFormRow(row)
// Email
row = XLFormRowDescriptor(tag: Tags.Email, rowType: XLFormRowDescriptorTypeEmail, title: "Email")
// validate the email
row.addValidator(XLFormValidator.emailValidator())
row.addValidator(XLFormValidator.email())
section.addFormRow(row)
// Twitter
row = XLFormRowDescriptor(tag: Tags.Name, rowType: XLFormRowDescriptorTypeTwitter, title: "Twitter")
row.disabled = NSNumber(bool: true)
row.disabled = NSNumber(value: true as Bool)
row.value = "@no_editable"
section.addFormRow(row)
@@ -121,7 +121,7 @@ class InputsFormViewController : XLFormViewController {
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("TextView With Label Example")
section = XLFormSectionDescriptor.formSection(withTitle: "TextView With Label Example")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.Number, rowType: XLFormRowDescriptorTypeTextView, title: "Notes")
@@ -134,10 +134,10 @@ class InputsFormViewController : XLFormViewController {
override func viewDidLoad()
{
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Save, target: self, action: "savePressed:")
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(InputsFormViewController.savePressed(_:)))
}
func savePressed(button: UIBarButtonItem)
@objc func savePressed(_ button: UIBarButtonItem)
{
let validationErrors : Array<NSError> = self.formValidationErrors() as! Array<NSError>
if (validationErrors.count > 0){
@@ -145,8 +145,11 @@ class InputsFormViewController : XLFormViewController {
return
}
self.tableView.endEditing(true)
let alertView = UIAlertView(title: "Valid Form", message: "No errors found", delegate: self, cancelButtonTitle: "OK")
alertView.show()
let alert = UIAlertController(title: "Valid Form", message: "No errors found!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
}
@@ -31,7 +31,7 @@ class MultivaluedFormViewController : XLFormViewController {
initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -45,7 +45,7 @@ class MultivaluedFormViewController : XLFormViewController {
form = XLFormDescriptor(title: "Multivalued Examples")
// Multivalued section
section = XLFormSectionDescriptor.formSectionWithTitle("Multivalued TextField", sectionOptions:XLFormSectionOptions.CanReorder.union(.CanInsert).union(.CanDelete), sectionInsertMode:.Button)
section = XLFormSectionDescriptor.formSection(withTitle: "Multivalued TextField", sectionOptions:XLFormSectionOptions.canReorder.union(.canInsert).union(.canDelete), sectionInsertMode:.button)
section.multivaluedAddButton!.title = "Add New Tag"
section.footerTitle = "XLFormSectionInsertModeButton sectionType adds a 'Add Item' (Add New Tag) button row as last cell."
// set up the row template
@@ -56,7 +56,7 @@ class MultivaluedFormViewController : XLFormViewController {
form.addFormSection(section)
// Another Multivalued section
section = XLFormSectionDescriptor.formSectionWithTitle("Multivalued ActionSheet Selector example", sectionOptions:XLFormSectionOptions.CanInsert.union(.CanDelete))
section = XLFormSectionDescriptor.formSection(withTitle: "Multivalued ActionSheet Selector example", sectionOptions:XLFormSectionOptions.canInsert.union(.canDelete))
section.footerTitle = "XLFormSectionInsertModeLastRow sectionType adds a '+' icon inside last table view cell allowing us to add a new row."
form.addFormSection(section)
row = XLFormRowDescriptor(tag: nil, rowType: XLFormRowDescriptorTypeSelectorActionSheet, title: "Tap to select..")
@@ -65,7 +65,7 @@ class MultivaluedFormViewController : XLFormViewController {
// Another one
section = XLFormSectionDescriptor.formSectionWithTitle("Multivalued Push Selector example", sectionOptions: XLFormSectionOptions.CanInsert.union(.CanDelete).union(.CanReorder), sectionInsertMode: .Button)
section = XLFormSectionDescriptor.formSection(withTitle: "Multivalued Push Selector example", sectionOptions: XLFormSectionOptions.canInsert.union(.canDelete).union(.canReorder), sectionInsertMode: .button)
section.footerTitle = "MultivaluedFormViewController.swift"
form.addFormSection(section)
row = XLFormRowDescriptor(tag: nil, rowType: XLFormRowDescriptorTypeSelectorPush, title: "Tap to select )..")
@@ -78,47 +78,50 @@ class MultivaluedFormViewController : XLFormViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Edit, target: self, action: "addDidTouch:")
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(MultivaluedFormViewController.addDidTouch(_:)))
}
//MARK: - Actions
func addDidTouch(sender: UIBarButtonItem) {
let actionSheet = UIActionSheet(title: nil, delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: "Remove Last Section", otherButtonTitles: "Add a section at the end", self.form!.disabled ? "Enable Form" : "Disable Form")
actionSheet.showInView(view)
}
//MARK: - UIActionSheetDelegate
override func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
if actionSheet.destructiveButtonIndex == buttonIndex {
if form.formSections.count > 0 {
@objc func addDidTouch(_ sender: UIBarButtonItem) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let removeAction = UIAlertAction(title: "Remove Last Section", style: .destructive, handler: { [weak self] alert in
guard let `self` = self else { return }
if self.form.formSections.count > 0 {
// remove last section
form.removeFormSectionAtIndex(UInt(form.formSections.count - 1))
self.form.removeFormSection(at: UInt(self.form.formSections.count - 1))
}
}
else if actionSheet.buttonTitleAtIndex(buttonIndex) == "Add a section at the end" {
// add a new section
// let dateString = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: NSDateFormatterStyle.ShortStyle, timeStyle: NSDateFormatterStyle.ShortStyle)
let newSection = XLFormSectionDescriptor.formSectionWithTitle("Section created at \(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: NSDateFormatterStyle.ShortStyle, timeStyle: NSDateFormatterStyle.ShortStyle))", sectionOptions:XLFormSectionOptions.CanInsert.union(.CanDelete))
})
let addSectionAction = UIAlertAction(title: "Add a section at the end", style: .default, handler: { [weak self] alert in
guard let `self` = self else { return }
let newSection = XLFormSectionDescriptor.formSection(withTitle: "Section created at \(DateFormatter.localizedString(from: Date(), dateStyle: DateFormatter.Style.short, timeStyle: DateFormatter.Style.short))", sectionOptions:XLFormSectionOptions.canInsert.union(.canDelete))
newSection.multivaluedTag = "multivaluedPushSelector_\(self.form.formSections.count)"
let newRow = XLFormRowDescriptor(tag: nil, rowType: XLFormRowDescriptorTypeSelectorPush, title: "Tap to select )..")
newRow.selectorOptions = ["Option 1", "Option 2", "Option 3"]
newSection.addFormRow(newRow)
form.addFormSection(newSection)
}
else {
form.disabled = !self.form.disabled
tableView.endEditing(true)
tableView.reloadData()
}
self.form.addFormSection(newSection)
})
let toggleAction = UIAlertAction(title: self.form!.isDisabled ? "Enable Form" : "Disable Form", style: .default, handler: { [weak self] alert in
guard let `self` = self else { return }
self.form.isDisabled = !self.form.isDisabled
self.tableView.endEditing(true)
self.tableView.reloadData()
})
actionSheet.addAction(addSectionAction)
actionSheet.addAction(removeAction)
actionSheet.addAction(cancelAction)
actionSheet.addAction(toggleAction)
present(actionSheet, animated: true, completion: nil)
}
}
class MultivaluedOnlyReorderViewController : XLFormViewController {
required init?(coder aDecoder: NSCoder) {
@@ -126,7 +129,7 @@ class MultivaluedOnlyReorderViewController : XLFormViewController {
self.initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
@@ -143,29 +146,31 @@ class MultivaluedOnlyReorderViewController : XLFormViewController {
form = XLFormDescriptor(title: "Only Reorder Examples")
// Multivalued Section with inline rows - section set up to support only reordering
section = XLFormSectionDescriptor.formSectionWithTitle("Reordering Inline Rows",
sectionOptions:.CanReorder)
section = XLFormSectionDescriptor.formSection(withTitle: "Reordering Inline Rows",
sectionOptions:.canReorder)
section.footerTitle = "XLFormRowDescriptorTypeDateInline row type"
form.addFormSection(section)
var idx = 0
for listItem in list {
let timeIntervalSinceNow = NSTimeInterval(secondsPerDay * ++idx)
idx += 1
let timeIntervalSinceNow = TimeInterval(secondsPerDay * idx)
row = XLFormRowDescriptor(tag: nil, rowType:XLFormRowDescriptorTypeDateInline, title: listItem)
row.value = NSDate(timeIntervalSinceNow:timeIntervalSinceNow)
row.value = Date(timeIntervalSinceNow:timeIntervalSinceNow)
section.addFormRow(row)
}
// Multivalued Section with common rows - section set up to support only reordering
section = XLFormSectionDescriptor.formSectionWithTitle("Reordering Rows", sectionOptions:.CanReorder)
section = XLFormSectionDescriptor.formSection(withTitle: "Reordering Rows", sectionOptions:.canReorder)
section.footerTitle = "XLFormRowDescriptorTypeInfo row type"
form.addFormSection(section)
idx = 0
for listItem in list {
let timeIntervalSinceNow = NSTimeInterval(secondsPerDay * ++idx)
idx += 1
let timeIntervalSinceNow = TimeInterval(secondsPerDay * idx)
row = XLFormRowDescriptor(tag: nil, rowType:XLFormRowDescriptorTypeInfo, title: listItem)
row.value = NSDateFormatter.localizedStringFromDate(NSDate(timeIntervalSinceNow:timeIntervalSinceNow), dateStyle: .MediumStyle, timeStyle: .NoStyle)
row.value = DateFormatter.localizedString(from: Date(timeIntervalSinceNow:timeIntervalSinceNow), dateStyle: .medium, timeStyle: .none)
section.addFormRow(row)
}
@@ -182,7 +187,7 @@ class MultivaluedOnlyInserViewController : XLFormViewController {
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
@@ -197,7 +202,7 @@ class MultivaluedOnlyInserViewController : XLFormViewController {
form = XLFormDescriptor(title: "Multivalued Only Insert")
section = XLFormSectionDescriptor.formSectionWithTitle("XLFormSectionInsertModeButton", sectionOptions:.CanInsert, sectionInsertMode:.Button)
section = XLFormSectionDescriptor.formSection(withTitle: "XLFormSectionInsertModeButton", sectionOptions:.canInsert, sectionInsertMode:.button)
form.addFormSection(section)
@@ -205,15 +210,15 @@ class MultivaluedOnlyInserViewController : XLFormViewController {
row.cellConfig["textField.placeholder"] = "Add a new tag"
section.multivaluedRowTemplate = row
section = XLFormSectionDescriptor.formSectionWithTitle("XLFormSectionInsertModeButton With Inline Cells", sectionOptions:.CanInsert, sectionInsertMode:.Button)
section = XLFormSectionDescriptor.formSection(withTitle: "XLFormSectionInsertModeButton With Inline Cells", sectionOptions:.canInsert, sectionInsertMode:.button)
row = XLFormRowDescriptor(tag: nil, rowType:XLFormRowDescriptorTypeDateInline)
row.value = NSDate()
row.value = Date()
row.title = "Date"
section.multivaluedRowTemplate = row
form.addFormSection(section)
section = XLFormSectionDescriptor.formSectionWithTitle("XLFormSectionInsertModeLastRow",
sectionOptions:.CanInsert, sectionInsertMode:.LastRow)
section = XLFormSectionDescriptor.formSection(withTitle: "XLFormSectionInsertModeLastRow",
sectionOptions:.canInsert, sectionInsertMode:.lastRow)
form.addFormSection(section)
for tag in nameList {
// add a row to the section, the row will be used to crete new rows.
@@ -233,19 +238,19 @@ class MultivaluedOnlyDeleteViewController : XLFormViewController {
initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Editing", style: .Plain, target: self, action: "toggleEditing:")
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Editing", style: .plain, target: self, action: #selector(MultivaluedOnlyDeleteViewController.toggleEditing(_:)))
}
func toggleEditing(sender : UIBarButtonItem) {
tableView.setEditing(!tableView.editing, animated: true)
sender.title = tableView.editing ? "Editing" : "Not Editing"
@objc func toggleEditing(_ sender : UIBarButtonItem) {
tableView.setEditing(!tableView.isEditing, animated: true)
sender.title = tableView.isEditing ? "Editing" : "Not Editing"
}
func initializeForm() {
@@ -258,7 +263,7 @@ class MultivaluedOnlyDeleteViewController : XLFormViewController {
form = XLFormDescriptor(title: "Multivalued Only Delete")
section = XLFormSectionDescriptor.formSectionWithTitle("", sectionOptions:.CanDelete)
section = XLFormSectionDescriptor.formSection(withTitle: "", sectionOptions:.canDelete)
section.footerTitle = "you can swipe to delete when table.editing = NO (Not Editing)"
form.addFormSection(section)
@@ -271,7 +276,7 @@ class MultivaluedOnlyDeleteViewController : XLFormViewController {
}
// Multivalued Section with inline row.
section = XLFormSectionDescriptor.formSectionWithTitle("", sectionOptions:.CanDelete)
section = XLFormSectionDescriptor.formSection(withTitle: "", sectionOptions:.canDelete)
section.footerTitle = "you can swipe to delete when table.editing = NO (Not Editing)"
form.addFormSection(section)
@@ -50,10 +50,10 @@ class XLFormCustomCell : XLFormBaseCell {
}
}
override func formDescriptorCellDidSelectedWithFormController(controller: XLFormViewController!) {
override func formDescriptorCellDidSelected(withForm controller: XLFormViewController!) {
// custom code here
// i.e new behaviour when cell has been selected
if let string = rowDescriptor?.value as? String where string == "Am a custom cell, select me!" {
if let string = rowDescriptor?.value as? String , string == "Am a custom cell, select me!" {
self.rowDescriptor?.value = string
}
else {
@@ -61,7 +61,7 @@ class XLFormCustomCell : XLFormBaseCell {
}
update()
controller.tableView.selectRowAtIndexPath(nil, animated: true, scrollPosition: .None)
controller.tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
}
}
@@ -27,7 +27,7 @@ import MapKit
class OthersFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let SwitchBool = "switchBool"
static let SwitchCheck = "switchCheck"
static let StepCounter = "stepCounter"
@@ -46,12 +46,10 @@ class OthersFormViewController : XLFormViewController {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
@@ -63,7 +61,7 @@ class OthersFormViewController : XLFormViewController {
form = XLFormDescriptor(title: "Other Cells")
section = XLFormSectionDescriptor.formSectionWithTitle("Other Cells")
section = XLFormSectionDescriptor.formSection(withTitle: "Other Cells")
section.footerTitle = "OthersFormViewController.swift"
form.addFormSection(section)
@@ -81,6 +79,12 @@ class OthersFormViewController : XLFormViewController {
row.selectorOptions = ["Apple", "Orange", "Pear"]
row.value = "Pear"
section.addFormRow(row)
row = XLFormRowDescriptor(tag: Tags.SegmentedControl, rowType: XLFormRowDescriptorTypeSegmentedInline, title: "Fruits Inline")
row.selectorOptions = ["Apple", "Orange", "Pear"]
row.value = "Pear"
section.addFormRow(row)
// Slider
@@ -99,31 +103,33 @@ class OthersFormViewController : XLFormViewController {
// Info cell
row = XLFormRowDescriptor(tag: Tags.Info, rowType: XLFormRowDescriptorTypeInfo)
row.title = "Version"
row.value = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
row.value = Bundle.main.infoDictionary!["CFBundleShortVersionString"]
section.addFormRow(row)
section = XLFormSectionDescriptor.formSectionWithTitle("Buttons")
section = XLFormSectionDescriptor.formSection(withTitle: "Buttons")
section.footerTitle = "Blue buttons will show a message when Switch is ON"
form.addFormSection(section)
// Button
row = XLFormRowDescriptor(tag: Tags.Button, rowType: XLFormRowDescriptorTypeButton, title: "Button")
row.cellConfig["textLabel.textColor"] = UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0)
row.action.formSelector = "didTouchButton:"
row.action.formSelector = #selector(OthersFormViewController.didTouchButton(_:))
section.addFormRow(row)
// Left Button
row = XLFormRowDescriptor(tag: Tags.ButtonLeftAligned, rowType: XLFormRowDescriptorTypeButton, title: "Button with Block")
row.cellConfig["textLabel.textColor"] = UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0)
row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.Left.rawValue
row.cellConfig["accessoryType"] = UITableViewCellAccessoryType.DisclosureIndicator.rawValue
row.cellConfig["textLabel.textAlignment"] = NSTextAlignment.left.rawValue
row.cellConfig["accessoryType"] = UITableViewCellAccessoryType.disclosureIndicator.rawValue
row.action.formBlock = { [weak self] (sender: XLFormRowDescriptor!) -> Void in
let switchRow = sender.sectionDescriptor.formDescriptor!.formRowWithTag(Tags.SwitchBool)!
if let value = switchRow.value where value.boolValue == true {
let alertView = UIAlertView(title: "Switch is ON", message: "Button has checked the switch value...", delegate: self, cancelButtonTitle: "OK")
alertView.show()
let switchRow = sender.sectionDescriptor.formDescriptor!.formRow(withTag: Tags.SwitchBool)!
if let value = switchRow.value , (value as AnyObject).boolValue == true {
let alert = UIAlertController(title: "Switch is ON", message: "Button has checked the switch value...", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self?.present(alert, animated: true, completion: nil)
}
self?.deselectFormRow(sender)
}
@@ -160,26 +166,30 @@ class OthersFormViewController : XLFormViewController {
self.form = form
}
func didTouchButton(sender: XLFormRowDescriptor) {
if sender.sectionDescriptor.formDescriptor.formRowWithTag(Tags.SwitchBool)?.value?.boolValue == true{
let alertView = UIAlertView(title: "Switch is ON", message: "Button has checked the switch value...", delegate: self, cancelButtonTitle: "OK")
alertView.show()
@objc func didTouchButton(_ sender: XLFormRowDescriptor) {
if (sender.sectionDescriptor.formDescriptor.formRow(withTag: Tags.SwitchBool)?.value as AnyObject).boolValue == true{
let alert = UIAlertController(title: "Switch is ON", message: "Button has checked the switch value...", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
self.deselectFormRow(sender)
}
override func viewDidLoad() {
super.viewDidLoad()
let barButton = UIBarButtonItem(title: "Disable", style: .Plain, target: self, action: "disableEnable:")
initializeForm()
let barButton = UIBarButtonItem(title: "Disable", style: .plain, target: self, action: #selector(OthersFormViewController.disableEnable(_:)))
barButton.possibleTitles = Set(["Disable", "Enable"])
navigationItem.rightBarButtonItem = barButton
}
func disableEnable(button : UIBarButtonItem) {
form.disabled = !form.disabled
button.title = form.disabled ? "Enable" : "Disable"
@objc func disableEnable(_ button : UIBarButtonItem) {
form.isDisabled = !form.isDisabled
button.title = form.isDisabled ? "Enable" : "Disable"
tableView.endEditing(true)
tableView.reloadData()
}
@@ -26,7 +26,7 @@
class BasicPredicateViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let HideRow = "tag1"
static let HideSection = "tag2"
@@ -35,7 +35,7 @@ class BasicPredicateViewController : XLFormViewController {
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -25,7 +25,7 @@
class BlogExampleViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let Hobbies = "hobbies"
static let Sport = "sport"
static let Film = "films1"
@@ -33,7 +33,7 @@ class BlogExampleViewController : XLFormViewController {
static let Music = "music"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -26,7 +26,7 @@
class PredicateFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let Text = "text"
static let Integer = "integer"
static let Switch = "switch"
@@ -34,7 +34,7 @@ class PredicateFormViewController : XLFormViewController {
static let Account = "account"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -77,7 +77,7 @@ class PredicateFormViewController : XLFormViewController {
// Predicate Disabling
row = XLFormRowDescriptor(tag: Tags.Date, rowType: XLFormRowDescriptorTypeDateInline, title:"Disabled")
row.value = NSDate()
row.value = Date()
section.addFormRow(row)
row.disabled = NSPredicate(format: "$\(Tags.Text).value contains[c] 'disable' OR ($\(Tags.Integer).value between {18, 60}) OR ($\(Tags.Switch).value == 0)")
section.hidden = NSPredicate(format: "($\(Tags.Text).value contains[c] 'disable') AND ($\(Tags.Integer).value between {18, 60}) AND ($\(Tags.Switch).value == 0)")
@@ -99,9 +99,9 @@ class PredicateFormViewController : XLFormViewController {
row.onChangeBlock = { [weak self] oldValue, newValue, _ in
let noValue = "No Value"
let message = "Old value: \(oldValue ?? noValue), New value: \(newValue ?? noValue)"
let alertView = UIAlertController(title: "Account Field changed", message: message, preferredStyle: .ActionSheet)
alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
self?.navigationController?.presentViewController(alertView, animated: true, completion: nil)
let alertView = UIAlertController(title: "Account Field changed", message: message, preferredStyle: .actionSheet)
alertView.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self?.navigationController?.present(alertView, animated: true, completion: nil)
}
self.form = form
@@ -31,7 +31,7 @@ class NativeEventFormViewController : XLFormViewController {
initializeForm()
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -50,7 +50,7 @@ class NativeEventFormViewController : XLFormViewController {
// Title
row = XLFormRowDescriptor(tag: "title", rowType: XLFormRowDescriptorTypeText)
row.cellConfigAtConfigure["textField.placeholder"] = "Title"
row.required = true
row.isRequired = true
section.addFormRow(row)
// Location
@@ -67,12 +67,12 @@ class NativeEventFormViewController : XLFormViewController {
// Starts
row = XLFormRowDescriptor(tag: "starts", rowType: XLFormRowDescriptorTypeDateTimeInline, title: "Starts")
row.value = NSDate(timeIntervalSinceNow: 60*60*24)
row.value = Date(timeIntervalSinceNow: 60*60*24)
section.addFormRow(row)
// Ends
row = XLFormRowDescriptor(tag: "ends", rowType: XLFormRowDescriptorTypeDateTimeInline, title: "Ends")
row.value = NSDate(timeIntervalSinceNow: 60*60*25)
row.value = Date(timeIntervalSinceNow: 60*60*25)
section.addFormRow(row)
section = XLFormSectionDescriptor.formSection()
@@ -139,83 +139,83 @@ class NativeEventFormViewController : XLFormViewController {
override func viewDidLoad(){
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Cancel, target: self, action: "cancelPressed:")
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Save, target: self, action: "savePressed:")
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(NativeEventFormViewController.cancelPressed(_:)))
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(NativeEventFormViewController.savePressed(_:)))
}
// MARK: XLFormDescriptorDelegate
override func formRowDescriptorValueHasChanged(formRow: XLFormRowDescriptor!, oldValue: AnyObject!, newValue: AnyObject!) {
override func formRowDescriptorValueHasChanged(_ formRow: XLFormRowDescriptor!, oldValue: Any!, newValue: Any!) {
super.formRowDescriptorValueHasChanged(formRow, oldValue: oldValue, newValue: newValue)
if formRow.tag == "alert" {
if !formRow.value!.valueData().isEqual(0) && oldValue.valueData().isEqual(0) {
if !((formRow.value! as AnyObject).valueData() as AnyObject).isEqual(0) && ((oldValue as AnyObject).valueData() as AnyObject).isEqual(0) {
let newRow = formRow.copy() as! XLFormRowDescriptor
newRow.tag = "secondAlert"
newRow.title = "Second Alert"
form.addFormRow(newRow, afterRow:formRow)
}
else if !oldValue.valueData().isEqual(0) && newValue.valueData().isEqual(0) {
form.removeFormRowWithTag("secondAlert")
else if !((oldValue as AnyObject).valueData() as AnyObject).isEqual(0) && ((newValue as AnyObject).valueData() as AnyObject).isEqual(0) {
form.removeFormRow(withTag: "secondAlert")
}
}
else if formRow.tag == "all-day" {
let startDateDescriptor = form.formRowWithTag("starts")!
let endDateDescriptor = form.formRowWithTag("ends")!
let dateStartCell: XLFormDateCell = startDateDescriptor.cellForFormController(self) as! XLFormDateCell
let dateEndCell: XLFormDateCell = endDateDescriptor.cellForFormController(self) as! XLFormDateCell
if formRow.value!.valueData() as? Bool == true {
let startDateDescriptor = form.formRow(withTag: "starts")!
let endDateDescriptor = form.formRow(withTag: "ends")!
let dateStartCell: XLFormDateCell = startDateDescriptor.cell(forForm: self) as! XLFormDateCell
let dateEndCell: XLFormDateCell = endDateDescriptor.cell(forForm: self) as! XLFormDateCell
if (formRow.value! as AnyObject).valueData() as? Bool == true {
startDateDescriptor.valueTransformer = DateValueTrasformer.self
endDateDescriptor.valueTransformer = DateValueTrasformer.self
dateStartCell.formDatePickerMode = .Date
dateEndCell.formDatePickerMode = .Date
dateStartCell.formDatePickerMode = .date
dateEndCell.formDatePickerMode = .date
}
else{
startDateDescriptor.valueTransformer = DateTimeValueTrasformer.self
endDateDescriptor.valueTransformer = DateTimeValueTrasformer.self
dateStartCell.formDatePickerMode = .DateTime
dateEndCell.formDatePickerMode = .DateTime
dateStartCell.formDatePickerMode = .dateTime
dateEndCell.formDatePickerMode = .dateTime
}
updateFormRow(startDateDescriptor)
updateFormRow(endDateDescriptor)
}
else if formRow.tag == "starts" {
let startDateDescriptor = form.formRowWithTag("starts")!
let endDateDescriptor = form.formRowWithTag("ends")!
if startDateDescriptor.value!.compare(endDateDescriptor.value as! NSDate) == .OrderedDescending {
let startDateDescriptor = form.formRow(withTag: "starts")!
let endDateDescriptor = form.formRow(withTag: "ends")!
if (startDateDescriptor.value! as AnyObject).compare(endDateDescriptor.value as! Date) == .orderedDescending {
// startDateDescriptor is later than endDateDescriptor
endDateDescriptor.value = NSDate(timeInterval: 60*60*24, sinceDate: startDateDescriptor.value as! NSDate)
endDateDescriptor.cellConfig.removeObjectForKey("detailTextLabel.attributedText")
endDateDescriptor.value = Date(timeInterval: 60*60*24, since: startDateDescriptor.value as! Date)
endDateDescriptor.cellConfig.removeObject(forKey: "detailTextLabel.attributedText")
updateFormRow(endDateDescriptor)
}
}
else if formRow.tag == "ends" {
let startDateDescriptor = form.formRowWithTag("starts")!
let endDateDescriptor = form.formRowWithTag("ends")!
let dateEndCell = endDateDescriptor.cellForFormController(self) as! XLFormDateCell
if startDateDescriptor.value!.compare(endDateDescriptor.value as! NSDate) == .OrderedDescending {
let startDateDescriptor = form.formRow(withTag: "starts")!
let endDateDescriptor = form.formRow(withTag: "ends")!
let dateEndCell = endDateDescriptor.cell(forForm: self) as! XLFormDateCell
if (startDateDescriptor.value! as AnyObject).compare(endDateDescriptor.value as! Date) == .orderedDescending {
// startDateDescriptor is later than endDateDescriptor
dateEndCell.update()
let newDetailText = dateEndCell.detailTextLabel!.text!
let strikeThroughAttribute = [NSStrikethroughStyleAttributeName : NSUnderlineStyle.StyleSingle.rawValue]
let strikeThroughAttribute = [NSAttributedStringKey.strikethroughStyle : NSUnderlineStyle.styleSingle.rawValue]
let strikeThroughText = NSAttributedString(string: newDetailText, attributes: strikeThroughAttribute)
endDateDescriptor.cellConfig["detailTextLabel.attributedText"] = strikeThroughText
updateFormRow(endDateDescriptor)
}
else{
let endDateDescriptor = self.form.formRowWithTag("ends")!
endDateDescriptor.cellConfig.removeObjectForKey("detailTextLabel.attributedText")
let endDateDescriptor = self.form.formRow(withTag: "ends")!
endDateDescriptor.cellConfig.removeObject(forKey: "detailTextLabel.attributedText")
updateFormRow(endDateDescriptor)
}
}
}
func cancelPressed(button: UIBarButtonItem){
dismissViewControllerAnimated(true, completion: nil)
@objc func cancelPressed(_ button: UIBarButtonItem){
dismiss(animated: true, completion: nil)
}
func savePressed(button: UIBarButtonItem){
@objc func savePressed(_ button: UIBarButtonItem){
let validationErrors : Array<NSError> = formValidationErrors() as! Array<NSError>
if (validationErrors.count > 0){
showFormValidationError(validationErrors.first)
@@ -230,7 +230,7 @@ class NativeEventNavigationViewController : UINavigationController {
override func viewDidLoad(){
super.viewDidLoad()
view.tintColor = .redColor()
view.tintColor = .red
}
}
@@ -27,7 +27,7 @@ import MapKit
// Mark - NSValueTransformer
class NSArrayValueTrasformer : NSValueTransformer {
class NSArrayValueTrasformer : ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return NSString.self
@@ -37,7 +37,7 @@ class NSArrayValueTrasformer : NSValueTransformer {
return false
}
override func transformedValue(value: AnyObject?) -> AnyObject? {
override func transformedValue(_ value: Any?) -> Any? {
if let arrayValue = value as? Array<AnyObject> {
return String(format: "%d Item%@", arrayValue.count, arrayValue.count > 1 ? "s" : "")
}
@@ -48,7 +48,7 @@ class NSArrayValueTrasformer : NSValueTransformer {
}
}
class ISOLanguageCodesValueTranformer : NSValueTransformer {
class ISOLanguageCodesValueTranformer : ValueTransformer {
override class func transformedValueClass() -> AnyClass {
return NSString.self
@@ -59,9 +59,9 @@ class ISOLanguageCodesValueTranformer : NSValueTransformer {
return false
}
override func transformedValue(value: AnyObject?) -> AnyObject? {
override func transformedValue(_ value: Any?) -> Any? {
if let stringValue = value as? String {
return NSLocale.currentLocale().displayNameForKey(NSLocaleLanguageCode, value: stringValue)
return (Locale.current as NSLocale).displayName(forKey: NSLocale.Key.languageCode, value: stringValue)
}
return nil
}
@@ -71,7 +71,7 @@ class ISOLanguageCodesValueTranformer : NSValueTransformer {
class SelectorsFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let Push = "selectorPush"
static let Popover = "selectorPopover"
static let ActionSheet = "selectorActionSheet"
@@ -90,7 +90,7 @@ class SelectorsFormViewController : XLFormViewController {
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -102,15 +102,15 @@ class SelectorsFormViewController : XLFormViewController {
override func viewDidLoad() {
super.viewDidLoad()
let barButton = UIBarButtonItem(title: "Disable", style: .Plain, target: self, action: "disableEnable:")
let barButton = UIBarButtonItem(title: "Disable", style: .plain, target: self, action: #selector(SelectorsFormViewController.disableEnable(_:)))
barButton.possibleTitles = Set(["Disable", "Enable"])
navigationItem.rightBarButtonItem = barButton
}
func disableEnable(button : UIBarButtonItem)
@objc func disableEnable(_ button : UIBarButtonItem)
{
form.disabled = !form.disabled
button.title = form.disabled ? "Enable" : "Disable"
form.isDisabled = !form.isDisabled
button.title = form.isDisabled ? "Enable" : "Disable"
tableView.endEditing(true)
tableView.reloadData()
}
@@ -122,7 +122,7 @@ class SelectorsFormViewController : XLFormViewController {
var row : XLFormRowDescriptor
form = XLFormDescriptor(title: "Selectors")
section = XLFormSectionDescriptor.formSectionWithTitle("Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Selectors")
section.footerTitle = "SelectorsFormViewController.swift"
form.addFormSection(section)
@@ -140,7 +140,7 @@ class SelectorsFormViewController : XLFormViewController {
// Selector Popover
if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad){
if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad){
row = XLFormRowDescriptor(tag: Tags.Popover, rowType:XLFormRowDescriptorTypeSelectorPopover, title:"PopOver")
row.selectorOptions = ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5", "Option 6"]
row.value = "Option 2"
@@ -169,7 +169,7 @@ class SelectorsFormViewController : XLFormViewController {
// --------- Fixed Controls
section = XLFormSectionDescriptor.formSectionWithTitle("Fixed Controls")
section = XLFormSectionDescriptor.formSection(withTitle: "Fixed Controls")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.Picker, rowType:XLFormRowDescriptorTypePicker)
@@ -178,7 +178,7 @@ class SelectorsFormViewController : XLFormViewController {
section.addFormRow(row)
// --------- Inline Selectors
section = XLFormSectionDescriptor.formSectionWithTitle("Inline Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Inline Selectors")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.MultipleSelector, rowType:XLFormRowDescriptorTypeSelectorPickerViewInline, title:"Inline Picker View")
@@ -187,7 +187,7 @@ class SelectorsFormViewController : XLFormViewController {
section.addFormRow(row)
// --------- MultipleSelector
section = XLFormSectionDescriptor.formSectionWithTitle("Multiple Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Multiple Selectors")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.MultipleSelector, rowType:XLFormRowDescriptorTypeMultipleSelector, title:"Multiple Selector")
@@ -206,26 +206,26 @@ class SelectorsFormViewController : XLFormViewController {
// Language multiple selector
row = XLFormRowDescriptor(tag: Tags.MultipleSelector, rowType:XLFormRowDescriptorTypeMultipleSelector, title:"Multiple Selector")
row.selectorOptions = NSLocale.ISOLanguageCodes()
row.selectorOptions = Locale.isoLanguageCodes
row.selectorTitle = "Languages"
row.valueTransformer = ISOLanguageCodesValueTranformer.self
row.value = NSLocale.preferredLanguages()
row.value = Locale.preferredLanguages
section.addFormRow(row)
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
if UIDevice.current.userInterfaceIdiom == .pad {
// Language multiple selector popover
row = XLFormRowDescriptor(tag: Tags.MultipleSelectorPopover, rowType:XLFormRowDescriptorTypeMultipleSelectorPopover, title:"Multiple Selector PopOver")
row.selectorOptions = NSLocale.ISOLanguageCodes()
row.selectorOptions = Locale.isoLanguageCodes
row.valueTransformer = ISOLanguageCodesValueTranformer.self
row.value = NSLocale.preferredLanguages()
row.value = Locale.preferredLanguages
section.addFormRow(row)
}
// --------- Dynamic Selectors
section = XLFormSectionDescriptor.formSectionWithTitle("Dynamic Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Dynamic Selectors")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.DynamicSelectors, rowType:XLFormRowDescriptorTypeButton, title:"Dynamic Selectors")
@@ -235,7 +235,7 @@ class SelectorsFormViewController : XLFormViewController {
// --------- Custom Selectors
section = XLFormSectionDescriptor.formSectionWithTitle("Custom Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Custom Selectors")
form.addFormSection(section)
row = XLFormRowDescriptor(tag: Tags.CustomSelectors, rowType:XLFormRowDescriptorTypeButton, title:"Custom Selectors")
@@ -244,7 +244,7 @@ class SelectorsFormViewController : XLFormViewController {
// --------- Selector definition types
section = XLFormSectionDescriptor.formSectionWithTitle("Selectors")
section = XLFormSectionDescriptor.formSection(withTitle: "Selectors")
form.addFormSection(section)
// selector with segue class
@@ -280,7 +280,7 @@ class SelectorsFormViewController : XLFormViewController {
}
override func storyboardForRow(formRow: XLFormRowDescriptor!) -> UIStoryboard! {
override func storyboard(forRow formRow: XLFormRowDescriptor!) -> UIStoryboard! {
return UIStoryboard(name: "iPhoneStoryboard", bundle:nil)
}
@@ -25,13 +25,13 @@
class UICustomizationFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let Name = "Name"
static let Button = "Button"
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.initializeForm()
}
@@ -55,15 +55,15 @@ class UICustomizationFormViewController : XLFormViewController {
// Name
row = XLFormRowDescriptor(tag: Tags.Name, rowType: XLFormRowDescriptorTypeText, title:"Name")
// change the background color
row.cellConfigAtConfigure["backgroundColor"] = UIColor.greenColor()
row.cellConfigAtConfigure["backgroundColor"] = UIColor.green
// font
row.cellConfig["textLabel.font"] = UIFont.systemFontOfSize(30)
row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 30)
// background color
row.cellConfig["textField.backgroundColor"] = UIColor.grayColor()
row.cellConfig["textField.backgroundColor"] = UIColor.gray
// font
row.cellConfig["textField.font"] = UIFont.systemFontOfSize(25)
row.cellConfig["textField.font"] = UIFont.systemFont(ofSize: 25)
// alignment
row.cellConfig["textField.textAlignment"] = NSTextAlignment.Right.rawValue
row.cellConfig["textField.textAlignment"] = NSTextAlignment.right.rawValue
section.addFormRow(row)
@@ -73,23 +73,23 @@ class UICustomizationFormViewController : XLFormViewController {
//Button
row = XLFormRowDescriptor(tag: Tags.Button, rowType: XLFormRowDescriptorTypeButton, title:"Button")
row.cellConfigAtConfigure["backgroundColor"] = UIColor.purpleColor()
row.cellConfig["textLabel.color"] = UIColor.whiteColor()
row.cellConfig["textLabel.font"] = UIFont.systemFontOfSize(40)
row.cellConfigAtConfigure["backgroundColor"] = UIColor.purple
row.cellConfig["textLabel.color"] = UIColor.white
row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 40)
section.addFormRow(row)
self.form = form
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// change cell height of a particular cell
if form.formRowAtIndex(indexPath)?.tag == "Name" {
if form.formRow(atIndex: indexPath)?.tag == "Name" {
return 60.0
}
else if form.formRowAtIndex(indexPath)?.tag == "Button" {
else if form.formRow(atIndex: indexPath)?.tag == "Button" {
return 100.0
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
@@ -26,7 +26,7 @@
class ValidationExamplesFormViewController : XLFormViewController {
private struct Tags {
fileprivate struct Tags {
static let ValidationName = "Name"
static let ValidationEmail = "Email"
static let ValidationPassword = "Password"
@@ -34,7 +34,7 @@ class ValidationExamplesFormViewController : XLFormViewController {
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
initializeForm()
}
@@ -60,8 +60,8 @@ class ValidationExamplesFormViewController : XLFormViewController {
// Name
row = XLFormRowDescriptor(tag: Tags.ValidationName, rowType: XLFormRowDescriptorTypeText, title:"Name")
row.cellConfigAtConfigure["textField.placeholder"] = "Required..."
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.Right.rawValue
row.required = true
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.right.rawValue
row.isRequired = true
row.value = "Martin"
section.addFormRow(row)
@@ -71,10 +71,10 @@ class ValidationExamplesFormViewController : XLFormViewController {
// Email
row = XLFormRowDescriptor(tag: Tags.ValidationEmail, rowType: XLFormRowDescriptorTypeText, title:"Email")
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.Right.rawValue
row.required = false
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.right.rawValue
row.isRequired = false
row.value = "not valid email"
row.addValidator(XLFormValidator.emailValidator())
row.addValidator(XLFormValidator.email())
section.addFormRow(row)
@@ -86,8 +86,8 @@ class ValidationExamplesFormViewController : XLFormViewController {
// Password
row = XLFormRowDescriptor(tag: Tags.ValidationPassword, rowType: XLFormRowDescriptorTypePassword, title:"Password")
row.cellConfigAtConfigure["textField.placeholder"] = "Required..."
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.Right.rawValue
row.required = true
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.right.rawValue
row.isRequired = true
row.addValidator(XLFormRegexValidator(msg: "At least 6, max 32 characters", andRegexString: "^(?=.*\\d)(?=.*[A-Za-z]).{6,32}$"))
section.addFormRow(row)
@@ -100,8 +100,8 @@ class ValidationExamplesFormViewController : XLFormViewController {
// Integer
row = XLFormRowDescriptor(tag: Tags.ValidationInteger, rowType:XLFormRowDescriptorTypeInteger, title:"Integer")
row.cellConfigAtConfigure["textField.placeholder"] = "Required..."
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.Right.rawValue
row.required = true
row.cellConfigAtConfigure["textField.textAlignment"] = NSTextAlignment.right.rawValue
row.isRequired = true
row.addValidator(XLFormRegexValidator(msg: "greater than 50 and less than 100", andRegexString: "^([5-9][0-9]|100)$"))
section.addFormRow(row)
@@ -111,30 +111,30 @@ class ValidationExamplesFormViewController : XLFormViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem?.target = self
navigationItem.rightBarButtonItem?.action = "validateForm:"
navigationItem.rightBarButtonItem?.action = #selector(ValidationExamplesFormViewController.validateForm(_:))
}
//MARK: Actions
func validateForm(buttonItem: UIBarButtonItem) {
@objc func validateForm(_ buttonItem: UIBarButtonItem) {
let array = formValidationErrors()
for errorItem in array {
for errorItem in array! {
let error = errorItem as! NSError
let validationStatus : XLFormValidationStatus = error.userInfo[XLValidationStatusErrorKey] as! XLFormValidationStatus
if validationStatus.rowDescriptor!.tag == Tags.ValidationName {
if let rowDescriptor = validationStatus.rowDescriptor, let indexPath = form.indexPathOfFormRow(rowDescriptor), let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.backgroundColor = .orangeColor()
UIView.animateWithDuration(0.3, animations: { () -> Void in
cell.backgroundColor = .whiteColor()
if let rowDescriptor = validationStatus.rowDescriptor, let indexPath = form.indexPath(ofFormRow: rowDescriptor), let cell = tableView.cellForRow(at: indexPath) {
cell.backgroundColor = .orange
UIView.animate(withDuration: 0.3, animations: { () -> Void in
cell.backgroundColor = .white
})
}
}
else if validationStatus.rowDescriptor!.tag == Tags.ValidationEmail ||
validationStatus.rowDescriptor!.tag == Tags.ValidationPassword ||
validationStatus.rowDescriptor!.tag == Tags.ValidationInteger {
if let rowDescriptor = validationStatus.rowDescriptor, let indexPath = form.indexPathOfFormRow(rowDescriptor), let cell = tableView.cellForRowAtIndexPath(indexPath) {
if let rowDescriptor = validationStatus.rowDescriptor, let indexPath = form.indexPath(ofFormRow: rowDescriptor), let cell = tableView.cellForRow(at: indexPath) {
self.animateCell(cell)
}
}
@@ -144,14 +144,14 @@ class ValidationExamplesFormViewController : XLFormViewController {
//MARK: - Helperph
func animateCell(cell: UITableViewCell) {
func animateCell(_ cell: UITableViewCell) {
let animation = CAKeyframeAnimation()
animation.keyPath = "position.x"
animation.values = [0, 20, -20, 10, 0]
animation.keyTimes = [0, (1 / 6.0), (3 / 6.0), (5 / 6.0), 1]
animation.keyTimes = [0, NSNumber(value: 1 / 6.0), NSNumber(value: 3 / 6.0), NSNumber(value: 5 / 6.0), 1]
animation.duration = 0.3
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
animation.additive = true
cell.layer.addAnimation(animation, forKey: "shake")
animation.isAdditive = true
cell.layer.add(animation, forKey: "shake")
}
}
+58 -19
View File
@@ -4,9 +4,11 @@ XLForm
By [XMARTLABS](http://xmartlabs.com).
[![Build Status](https://travis-ci.org/xmartlabs/XLForm.svg?branch=master)](https://travis-ci.org/xmartlabs/XLForm)
[![license](https://img.shields.io/badge/pod-3.1.1-blue.svg)](https://github.com/xmartlabs/XLForm/releases)
<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 2 native implementation we have recently created [Eureka], a complete re-design of XLForm in Swift 2.** *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 and with more features.**
We are not implementing any new features for XLForm anymore. However, if a critical issue arises we will fix it.
Purpose
--------------
@@ -15,7 +17,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
![Screenshot of native Calendar Event Example](Examples/Objective-C/Examples/RealExamples/XLForm.gif)
@@ -154,6 +156,8 @@ A form definition is a `XLFormDescriptor` instance that contains one or more sec
row = [XLFormRowDescriptor formRowDescriptorWithTag:@"starts" rowType:XLFormRowDescriptorTypeDateTimeInline title:@"Starts"];
row.value = [NSDate dateWithTimeIntervalSinceNow:60*60*24];
[section addFormRow:row];
self.form = form;
}
```
@@ -180,7 +184,7 @@ How to run XLForm examples
Rows
---------------------
####Input Rows
#### Input Rows
![Screenshot of Input Examples](Examples/Objective-C/Examples/Inputs/XLForm-Inputs.gif)
@@ -251,7 +255,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:
@@ -318,7 +322,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.
@@ -425,7 +429,7 @@ section.addFormRow(row)
self.form = form;
```
####Boolean Rows
#### Boolean Rows
XLForms supports 2 types of boolean controls:
@@ -443,9 +447,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:
@@ -467,7 +471,7 @@ You can set the stepper paramaters easily:
[row.cellConfigAtConfigure setObject:@100 forKey:@"stepControl.maximumValue"];
```
#####Slider
##### Slider
XLForms supports counting using UISlider control:
@@ -488,11 +492,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.
@@ -765,7 +769,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.
@@ -775,7 +779,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:
@@ -864,6 +868,7 @@ You may want to set up another properties of the `UITableViewCell`. To set up an
You just have to add the properties to `cellConfig` or `cellConfigAtConfigure` dictionary property of `XLFormRowDescriptor`.
The main difference between `cellConfig` and `cellConfigAtConfigure` is the time when the property is set up. `cellConfig` properties are set up each time a cell is about to be displayed. `cellConfigAtConfigure`, on the other hand, set up the property just after the init method of the cell is called and only one time.
Since version 3.3.0 you can also use `cellConfigForSelector` to configure how the cells of the `XLFormOptionsViewController` look like when it is shown for a selector row.
For instance if you want to set up the placeholder you can do the following:
@@ -894,6 +899,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`.
@@ -1005,7 +1029,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:
@@ -1083,13 +1107,28 @@ XLFormRowDescriptor* row = ...
row.height = 55;
```
#### How to change the appearance of the cells of a selector view controller (XLFormOptionsViewController)
To change the appearance of the cells of a XLFormOptionsViewController you can use the `cellConfigForSelector` property on the row descriptor.
Example:
```
[row.cellConfigForSelector setObject:[UIColor redColor] forKey:@"textLabel.textColor"];
```
#### How to limit the characters of a XLFormTextFieldCell or a XLFormTextViewCell
You can make this happen using the `textFieldMaxNumberOfCharacters` and the `textViewMaxNumberOfCharacters` respectively.
```
[row.cellConfigAtConfigure setObject:@(20) forKey:@"textViewMaxNumberOfCharacters"];
```
Installation
--------------------------
## CocoaPods
1. Add the following line in the project's Podfile file:
`pod 'XLForm', '~> 3.0'`.
`pod 'XLForm', '~> 4.0'`.
2. Run the command `pod install` from the Podfile folder directory.
XLForm **has no** dependencies over other pods.
@@ -1119,7 +1158,7 @@ For further details on how to create and configure the bridging header file visi
In your `Cartfile` add:
```
github "xmartlabs/XLForm" ~> 3.0
github "xmartlabs/XLForm" ~> 4.0
```
## Using git submodules
@@ -1142,8 +1181,8 @@ Requirements
-----------------------------
* ARC
* iOS 7.0 and above
* XCode 6.3+
* iOS 9.0 and above
* XCode 9.0+
Release Notes
+2 -2
View File
@@ -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', 'iphonesimulator12.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=12.2,name=iPhone 8' -configuration Release clean test | xcpretty -c ; exit ${PIPESTATUS[0]}") rescue nil
end
def tests_failed
+3 -2
View File
@@ -2,8 +2,9 @@ source 'https://github.com/CocoaPods/Specs.git'
project 'XLForm Tests'
inhibit_all_warnings!
platform :ios, '7.0'
platform :ios, '9.0'
target 'XLForm Tests' do
pod 'Expecta', '~> 0.3.0'
pod 'Expecta', '~> 1.0'
pod 'XLForm', :path => '../'
end
+94 -51
View File
@@ -7,19 +7,22 @@
objects = {
/* Begin PBXBuildFile section */
17538872B9BB29167787CF50 /* libPods-XLForm Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E68572C5C8328F0F177BBCA1 /* libPods-XLForm Tests.a */; };
03885A911D7DD3BD00CC183A /* XLTestTextFieldProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 03885A901D7DD3BD00CC183A /* XLTestTextFieldProperties.m */; };
28657A3E1990879200CE8180 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28657A3D1990879200CE8180 /* XCTest.framework */; };
28657A401990879200CE8180 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28657A3F1990879200CE8180 /* Foundation.framework */; };
28657A421990879200CE8180 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28657A411990879200CE8180 /* UIKit.framework */; };
28657A481990879200CE8180 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 28657A461990879200CE8180 /* InfoPlist.strings */; };
28657A5219914F9700CE8180 /* XLTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 28657A5119914F9700CE8180 /* XLTestCase.m */; };
28657A54199154EE00CE8180 /* XLFormValidatorsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 28657A53199154EE00CE8180 /* XLFormValidatorsTests.m */; };
39585558ED414BFBE6FFB93C /* libPods-XLForm Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8189C74AF1BF64FDF4D14AE3 /* libPods-XLForm Tests.a */; };
3C5B9B7A1AC0BA33000AF1BA /* XLFormExampleTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C5B9B791AC0BA33000AF1BA /* XLFormExampleTest.m */; };
3C9817861AC30616003F6ABD /* UITextField+Test.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9817851AC30616003F6ABD /* UITextField+Test.m */; };
6233D65F1D7DF022000E7716 /* XLTestTextViewProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 6233D65E1D7DF022000E7716 /* XLTestTextViewProperties.m */; };
BFD111841AD8323900943D23 /* XLTestHideAndShow.m in Sources */ = {isa = PBXBuildFile; fileRef = BFD111831AD8323900943D23 /* XLTestHideAndShow.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
03885A901D7DD3BD00CC183A /* XLTestTextFieldProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLTestTextFieldProperties.m; path = Test/XLTestTextFieldProperties.m; sourceTree = "<group>"; };
28657A3A1990879200CE8180 /* XLForm Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "XLForm Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
28657A3D1990879200CE8180 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
28657A3F1990879200CE8180 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
@@ -30,16 +33,14 @@
28657A5019914F9700CE8180 /* XLTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XLTestCase.h; path = Test/XLTestCase.h; sourceTree = "<group>"; };
28657A5119914F9700CE8180 /* XLTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLTestCase.m; path = Test/XLTestCase.m; sourceTree = "<group>"; };
28657A53199154EE00CE8180 /* XLFormValidatorsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLFormValidatorsTests.m; path = Test/XLFormValidatorsTests.m; sourceTree = "<group>"; };
35038A584FCFD0693D23F189 /* Pods-XLForm Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests.debug.xcconfig"; sourceTree = "<group>"; };
3BE0FA85B15844909EF36AB4 /* Pods-XLForm Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests.release.xcconfig"; sourceTree = "<group>"; };
3C5B9B791AC0BA33000AF1BA /* XLFormExampleTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLFormExampleTest.m; path = Test/XLFormExampleTest.m; sourceTree = "<group>"; };
3C9817841AC30616003F6ABD /* UITextField+Test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UITextField+Test.h"; path = "Helpers/UITextField+Test.h"; sourceTree = "<group>"; };
3C9817851AC30616003F6ABD /* UITextField+Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UITextField+Test.m"; path = "Helpers/UITextField+Test.m"; sourceTree = "<group>"; };
8ADC094C94CA7ABBB8134573 /* 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>"; };
6233D65E1D7DF022000E7716 /* XLTestTextViewProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLTestTextViewProperties.m; path = Test/XLTestTextViewProperties.m; sourceTree = "<group>"; };
8189C74AF1BF64FDF4D14AE3 /* libPods-XLForm Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-XLForm Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
BFD111831AD8323900943D23 /* XLTestHideAndShow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XLTestHideAndShow.m; path = Test/XLTestHideAndShow.m; sourceTree = "<group>"; };
C6B20EA1A9D9591335BEE81F /* 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>"; };
CEC7E8601D7342BFAF4C4060 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
E68572C5C8328F0F177BBCA1 /* libPods-XLForm Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-XLForm Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
D5A9B3DB06904B24F1A8EA24 /* Pods-XLForm Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests.release.xcconfig"; sourceTree = "<group>"; };
F9D7EFDB6BD5884E5923B6AC /* Pods-XLForm Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-XLForm Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -50,20 +51,29 @@
28657A3E1990879200CE8180 /* XCTest.framework in Frameworks */,
28657A421990879200CE8180 /* UIKit.framework in Frameworks */,
28657A401990879200CE8180 /* Foundation.framework in Frameworks */,
17538872B9BB29167787CF50 /* libPods-XLForm Tests.a in Frameworks */,
39585558ED414BFBE6FFB93C /* libPods-XLForm Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
142BA587E51B2D88244F04F1 /* Pods */ = {
isa = PBXGroup;
children = (
F9D7EFDB6BD5884E5923B6AC /* Pods-XLForm Tests.debug.xcconfig */,
D5A9B3DB06904B24F1A8EA24 /* Pods-XLForm Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
28657A2F19907FBE00CE8180 = {
isa = PBXGroup;
children = (
28657A431990879200CE8180 /* XLForm Tests */,
28657A3C1990879200CE8180 /* Frameworks */,
28657A3B1990879200CE8180 /* Products */,
52B313F2682BC45F8E9E8132 /* Pods */,
142BA587E51B2D88244F04F1 /* Pods */,
);
sourceTree = "<group>";
};
@@ -81,8 +91,7 @@
28657A3D1990879200CE8180 /* XCTest.framework */,
28657A3F1990879200CE8180 /* Foundation.framework */,
28657A411990879200CE8180 /* UIKit.framework */,
CEC7E8601D7342BFAF4C4060 /* libPods.a */,
E68572C5C8328F0F177BBCA1 /* libPods-XLForm Tests.a */,
8189C74AF1BF64FDF4D14AE3 /* libPods-XLForm Tests.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -115,6 +124,8 @@
28657A5019914F9700CE8180 /* XLTestCase.h */,
28657A5119914F9700CE8180 /* XLTestCase.m */,
28657A53199154EE00CE8180 /* XLFormValidatorsTests.m */,
03885A901D7DD3BD00CC183A /* XLTestTextFieldProperties.m */,
6233D65E1D7DF022000E7716 /* XLTestTextViewProperties.m */,
);
name = Tests;
sourceTree = "<group>";
@@ -128,17 +139,6 @@
name = Helpers;
sourceTree = "<group>";
};
52B313F2682BC45F8E9E8132 /* Pods */ = {
isa = PBXGroup;
children = (
C6B20EA1A9D9591335BEE81F /* Pods.debug.xcconfig */,
8ADC094C94CA7ABBB8134573 /* Pods.release.xcconfig */,
35038A584FCFD0693D23F189 /* Pods-XLForm Tests.debug.xcconfig */,
3BE0FA85B15844909EF36AB4 /* Pods-XLForm Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -146,12 +146,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 28657A4C1990879200CE8180 /* Build configuration list for PBXNativeTarget "XLForm Tests" */;
buildPhases = (
6B058765CC1143829C6943B9 /* 📦 Check Pods Manifest.lock */,
29CB07B4E0344AEB95FE5406 /* [CP] Check Pods Manifest.lock */,
28657A361990879200CE8180 /* Sources */,
28657A371990879200CE8180 /* Frameworks */,
28657A381990879200CE8180 /* Resources */,
3E5FCF05A57F40C6AF367F6D /* 📦 Copy Pods Resources */,
6A2C507B76209618EDA57426 /* 📦 Embed Pods Frameworks */,
7E96395A3A94BDD9487AE471 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -168,7 +167,7 @@
28657A3019907FBE00CE8180 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastUpgradeCheck = 0900;
};
buildConfigurationList = 28657A3319907FBE00CE8180 /* Build configuration list for PBXProject "XLForm Tests" */;
compatibilityVersion = "Xcode 3.2";
@@ -199,49 +198,40 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3E5FCF05A57F40C6AF367F6D /* 📦 Copy Pods Resources */ = {
29CB07B4E0344AEB95FE5406 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "📦 Copy Pods Resources";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-XLForm Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
6A2C507B76209618EDA57426 /* 📦 Embed Pods Frameworks */ = {
7E96395A3A94BDD9487AE471 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh",
"${PODS_ROOT}/../../XLForm/XLForm.bundle",
);
name = "📦 Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/XLForm.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
6B058765CC1143829C6943B9 /* 📦 Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -253,7 +243,9 @@
files = (
28657A54199154EE00CE8180 /* XLFormValidatorsTests.m in Sources */,
28657A5219914F9700CE8180 /* XLTestCase.m in Sources */,
03885A911D7DD3BD00CC183A /* XLTestTextFieldProperties.m in Sources */,
BFD111841AD8323900943D23 /* XLTestHideAndShow.m in Sources */,
6233D65F1D7DF022000E7716 /* XLTestTextViewProperties.m in Sources */,
3C5B9B7A1AC0BA33000AF1BA /* XLFormExampleTest.m in Sources */,
3C9817861AC30616003F6ABD /* UITextField+Test.m in Sources */,
);
@@ -276,6 +268,31 @@
28657A3419907FBE00CE8180 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
@@ -283,12 +300,36 @@
28657A3519907FBE00CE8180 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
};
name = Release;
};
28657A4D1990879200CE8180 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 35038A584FCFD0693D23F189 /* Pods-XLForm Tests.debug.xcconfig */;
baseConfigurationReference = F9D7EFDB6BD5884E5923B6AC /* Pods-XLForm Tests.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -326,9 +367,10 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "XLForm Tests/XLForm Tests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
WRAPPER_EXTENSION = xctest;
@@ -337,7 +379,7 @@
};
28657A4E1990879200CE8180 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3BE0FA85B15844909EF36AB4 /* Pods-XLForm Tests.release.xcconfig */;
baseConfigurationReference = D5A9B3DB06904B24F1A8EA24 /* Pods-XLForm Tests.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -369,8 +411,9 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "XLForm Tests/XLForm Tests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.1;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.xmartlabs.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -23,10 +23,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -39,15 +40,19 @@
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
@@ -62,10 +67,10 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
@@ -0,0 +1,66 @@
//
// XLTestTextFieldProperties.m
// XLForm Tests
//
// Created by Claus on 9/5/16.
//
//
#import "XLTestCase.h"
#import <XLForm/XLFormTextFieldCell.h>
#import <UIKit/UIKit.h>
@interface XLTestTextFieldProperties : XLTestCase
@end
@implementation XLTestTextFieldProperties
- (void)testPropertiesGetSet
{
// Get the tableView
UITableView * tableView = self.formController.tableView;
UITableViewCell * cell = [self.formController tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
// Check if the cell contains the correct properties
expect(cell).to.beKindOf([XLFormTextFieldCell class]);
XLFormTextFieldCell * textFieldCell = (XLFormTextFieldCell *)cell;
expect(textFieldCell.textFieldLengthPercentage).to.equal(0.3);
expect(textFieldCell.textFieldMaxNumberOfCharacters).to.equal(10);
}
- (void)testMaxNumbersOfCharacters
{
// Get the tableView
UITableView * tableView = self.formController.tableView;
UITableViewCell * cell = [self.formController tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
expect(cell).to.beKindOf([XLFormTextFieldCell class]);
XLFormTextFieldCell * textFieldCell = (XLFormTextFieldCell *)cell;
// Check if range check works
expect(cell).to.conformTo(@protocol(UITextFieldDelegate));
id<UITextFieldDelegate> textFieldDelegate = (id<UITextFieldDelegate>)cell;
NSRange range = NSMakeRange(0, 0);
expect([textFieldDelegate textField:textFieldCell.textField shouldChangeCharactersInRange:range replacementString:@"123"]).to.beTruthy();
expect([textFieldDelegate textField:textFieldCell.textField shouldChangeCharactersInRange:range replacementString:@"1234567890"]).to.beTruthy();
expect([textFieldDelegate textField:textFieldCell.textField shouldChangeCharactersInRange:range replacementString:@"12345678901"]).to.beFalsy();
}
#pragma mark - Build Form
-(void)buildForm
{
XLFormDescriptor * form = [XLFormDescriptor formDescriptor];
XLFormSectionDescriptor * section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
XLFormRowDescriptor * row = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeText];
[row.cellConfigAtConfigure setObject:@(0.3) forKey:XLFormTextFieldLengthPercentage];
[row.cellConfigAtConfigure setObject:@(10) forKey:XLFormTextFieldMaxNumberOfCharacters];
[section addFormRow:row];
self.formController.form = form;
}
@end
@@ -0,0 +1,66 @@
//
// XLTestTextViewProperties.m
// XLForm Tests
//
// Created by Claus on 9/5/16.
//
//
#import "XLTestCase.h"
#import <XLForm/XLFormTextViewCell.h>
#import <UIKit/UIKit.h>
@interface XLTestTextViewProperties : XLTestCase
@end
@implementation XLTestTextViewProperties
- (void)testPropertiesGetSet
{
// Get the tableView
UITableView * tableView = self.formController.tableView;
UITableViewCell * cell = [self.formController tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
// Check if the cell contains the correct properties
expect(cell).to.beKindOf([XLFormTextViewCell class]);
XLFormTextViewCell * textViewCell = (XLFormTextViewCell *)cell;
expect(textViewCell.textViewLengthPercentage).to.equal(0.3);
expect(textViewCell.textViewMaxNumberOfCharacters).to.equal(10);
}
- (void)testMaxNumbersOfCharacters
{
// Get the tableView
UITableView * tableView = self.formController.tableView;
UITableViewCell * cell = [self.formController tableView:tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
expect(cell).to.beKindOf([XLFormTextViewCell class]);
XLFormTextViewCell * textViewCell = (XLFormTextViewCell *)cell;
// Check if range check works
expect(cell).to.conformTo(@protocol(UITextViewDelegate));
id<UITextViewDelegate> textFieldDelegate = (id<UITextViewDelegate>)cell;
NSRange range = NSMakeRange(0, 0);
expect([textFieldDelegate textView:textViewCell.textView shouldChangeTextInRange:range replacementText:@"123"]).to.beTruthy();
expect([textFieldDelegate textView:textViewCell.textView shouldChangeTextInRange:range replacementText:@"1234567890"]).to.beTruthy();
expect([textFieldDelegate textView:textViewCell.textView shouldChangeTextInRange:range replacementText:@"12345678901"]).to.beFalsy();
}
#pragma mark - Build Form
-(void)buildForm
{
XLFormDescriptor * form = [XLFormDescriptor formDescriptor];
XLFormSectionDescriptor * section = [XLFormSectionDescriptor formSection];
[form addFormSection:section];
XLFormRowDescriptor * row = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeTextView];
[row.cellConfigAtConfigure setObject:@(0.3) forKey:XLFormTextViewLengthPercentage];
[row.cellConfigAtConfigure setObject:@(10) forKey:XLFormTextViewMaxNumberOfCharacters];
[section addFormRow:row];
self.formController.form = form;
}
@end
+1 -1
View File
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.xmartlabs.${PRODUCT_NAME:rfc1034identifier}</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'XLForm'
s.version = '3.2.0'
s.version = '4.0.1'
s.license = { :type => 'MIT' }
s.summary = 'XLForm is the most flexible and powerful iOS library to create dynamic table-view forms.'
s.description = <<-DESC
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/xmartlabs/XLForm.git', :tag => s.version }
s.source_files = 'XLForm/XL/**/*.{h,m}'
s.requires_arc = true
s.ios.deployment_target = '7.0'
s.ios.deployment_target = '9.0'
s.ios.frameworks = 'UIKit', 'Foundation', 'CoreGraphics'
s.resource = 'XLForm/XLForm.bundle'
end
+25 -3
View File
@@ -414,7 +414,7 @@
E267FD171BE8048900F86B42 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0710;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = XLForm;
TargetAttributes = {
E267FD1F1BE8048900F86B42 = {
@@ -505,13 +505,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -534,7 +544,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -552,13 +562,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
@@ -575,7 +595,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -588,6 +608,7 @@
E267FD291BE8048900F86B42 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@@ -604,6 +625,7 @@
E267FD2A1BE8048900F86B42 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+2 -2
View File
@@ -42,8 +42,8 @@
@protocol XLFormReturnKeyProtocol
@property UIReturnKeyType returnKeyType;
@property UIReturnKeyType nextReturnKeyType;
@property (nonatomic, assign) UIReturnKeyType returnKeyType;
@property (nonatomic, assign) UIReturnKeyType nextReturnKeyType;
@end
+1 -1
View File
@@ -27,7 +27,7 @@
@implementation XLFormBaseCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
+2 -2
View File
@@ -28,7 +28,7 @@
@implementation XLFormButtonCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
return [super initWithStyle:style reuseIdentifier:reuseIdentifier];
}
@@ -57,7 +57,7 @@
[self.tintColor getRed:&red green:&green blue:&blue alpha:&alpha];
self.textLabel.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:(isDisabled ? 0.3 : 1.0)];
}
self.detailTextLabel.text = self.rowDescriptor.value;
}
+5 -4
View File
@@ -34,9 +34,10 @@ typedef NS_ENUM(NSUInteger, XLFormDateDatePickerMode) {
@interface XLFormDateCell : XLFormBaseCell
@property (nonatomic) XLFormDateDatePickerMode formDatePickerMode;
@property (nonatomic) NSDate *minimumDate;
@property (nonatomic) NSDate *maximumDate;
@property (nonatomic) NSInteger minuteInterval;
@property (nonatomic, assign) XLFormDateDatePickerMode formDatePickerMode;
@property (nonatomic, copy ) NSDate *minimumDate;
@property (nonatomic, copy ) NSDate *maximumDate;
@property (nonatomic, assign) NSInteger minuteInterval;
@property (nonatomic, copy ) NSLocale *locale;
@end
+24 -4
View File
@@ -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,16 +175,24 @@
}
}
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]){
NSDateComponents *time = [[NSCalendar currentCalendar] components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
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
@@ -195,6 +205,7 @@
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimer] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimerInline]){
datePicker.datePickerMode = UIDatePickerModeCountDownTimer;
datePicker.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
}
else{
datePicker.datePickerMode = UIDatePickerModeDateAndTime;
@@ -208,6 +219,10 @@
if (self.maximumDate)
datePicker.maximumDate = self.maximumDate;
if (self.locale) {
datePicker.locale = self.locale;
}
}
#pragma mark - Properties
@@ -221,6 +236,11 @@
return _datePicker;
}
-(void)setLocale:(NSLocale *)locale
{
_locale = locale;
_dateFormatter.locale = locale;
}
#pragma mark - Target Action
+6 -11
View File
@@ -37,16 +37,6 @@
return YES;
}
#pragma mark - Properties
-(UIDatePicker *)datePicker
{
if (_datePicker) return _datePicker;
_datePicker = [UIDatePicker autolayoutView];
[_datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
return _datePicker;
}
#pragma mark- Target Action
- (void)datePickerValueChanged:(UIDatePicker *)sender
@@ -66,7 +56,12 @@
-(void)configure
{
[super configure];
[self.contentView addSubview:self.datePicker];
UIDatePicker *datePicker = [UIDatePicker autolayoutView];
[datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.contentView addSubview:datePicker];
_datePicker = datePicker;
[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.datePicker attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[datePicker]-0-|" options:0 metrics:0 views:@{@"datePicker" : self.datePicker}]];
}
+14 -15
View File
@@ -29,7 +29,6 @@
@interface XLFormImageCell() <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
UIPopoverController *popoverController;
UIImagePickerController *imagePickerController;
UIAlertController *alertController;
}
@@ -72,6 +71,7 @@
- (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller
{
__weak typeof(self) weak = self;
alertController = [UIAlertController alertControllerWithTitle: self.rowDescriptor.title
message: nil
preferredStyle: UIAlertControllerStyleActionSheet];
@@ -79,14 +79,14 @@
[alertController addAction:[UIAlertAction actionWithTitle: NSLocalizedString(@"Choose From Library", nil)
style: UIAlertActionStyleDefault
handler: ^(UIAlertAction * _Nonnull action) {
[self openImage:UIImagePickerControllerSourceTypePhotoLibrary];
[weak openImage:UIImagePickerControllerSourceTypePhotoLibrary];
}]];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[alertController addAction:[UIAlertAction actionWithTitle: NSLocalizedString(@"Take Photo", nil)
style: UIAlertActionStyleDefault
handler: ^(UIAlertAction * _Nonnull action) {
[self openImage:UIImagePickerControllerSourceTypeCamera];
[weak openImage:UIImagePickerControllerSourceTypeCamera];
}]];
}
@@ -101,7 +101,7 @@
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.formViewController presentViewController:alertController animated: true completion: nil];
[weak.formViewController presentViewController:self->alertController animated: true completion: nil];
});
}
@@ -113,16 +113,15 @@
imagePickerController.sourceType = source;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
[popoverController presentPopoverFromRect: self.contentView.frame
inView: self.formViewController.view
permittedArrowDirections: UIPopoverArrowDirectionAny
animated: YES];
} else {
[self.formViewController presentViewController: imagePickerController
animated: YES
completion: nil];
imagePickerController.modalPresentationStyle = UIModalPresentationPopover;
imagePickerController.popoverPresentationController.sourceRect = self.contentView.frame;
imagePickerController.popoverPresentationController.sourceView = self.formViewController.view;
imagePickerController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[self.formViewController presentViewController: imagePickerController
animated: YES
completion: nil];
}
#pragma mark - UIImagePickerControllerDelegate
@@ -138,8 +137,8 @@
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if (popoverController && popoverController.isPopoverVisible) {
[popoverController dismissPopoverAnimated: YES];
if (self.formViewController.presentedViewController && self.formViewController.presentedViewController.modalPresentationStyle == UIModalPresentationPopover) {
[self.formViewController dismissViewControllerAnimated:YES completion:nil];
}
} else {
[self.formViewController dismissViewControllerAnimated: YES completion: nil];
+16 -73
View File
@@ -28,11 +28,6 @@
#import "NSObject+XLFormAdditions.h"
#import "XLFormLeftRightSelectorCell.h"
@interface XLFormLeftRightSelectorCell() <UIActionSheetDelegate>
@end
@implementation XLFormLeftRightSelectorCell
{
UITextField * _constraintTextField;
@@ -195,76 +190,24 @@
-(void)leftButtonPressed:(UIButton *)leftButton
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak typeof(self) weak = self;
for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
[actionSheet addButtonWithTitle:[leftOption.leftValue displayText]];
[alertController addAction:[UIAlertAction actionWithTitle:[leftOption.leftValue displayText]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
weak.rowDescriptor.value = [weak chooseNewRightValueFromOption:leftOption];
weak.rowDescriptor.leftRightSelectorLeftOptionSelected = [weak leftOptionForDescription:[leftOption.leftValue displayText]].leftValue;
[weak.formViewController updateFormRow:weak.rowDescriptor];
}]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
actionSheet.tag = [self.rowDescriptor hash];
[actionSheet showInView:self.formViewController.view];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
__weak __typeof(self)weakSelf = self;
for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
[alertController addAction:[UIAlertAction actionWithTitle:[leftOption.leftValue displayText]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
weakSelf.rowDescriptor.value = [self chooseNewRightValueFromOption:leftOption];
weakSelf.rowDescriptor.leftRightSelectorLeftOptionSelected = [self leftOptionForDescription:[leftOption.leftValue displayText]].leftValue;
[weakSelf.formViewController updateFormRow:weakSelf.rowDescriptor];
}]];
}
[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
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (XLFormLeftRightSelectorOption * leftOption in self.rowDescriptor.selectorOptions) {
[actionSheet addButtonWithTitle:[leftOption.leftValue displayText]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
actionSheet.tag = [self.rowDescriptor hash];
[actionSheet showInView:self.formViewController.view];
}
#endif
#endif
[self.formViewController presentViewController:alertController animated:YES completion:nil];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([actionSheet cancelButtonIndex] != buttonIndex){
NSString * title = [actionSheet buttonTitleAtIndex:buttonIndex];
if (![self.rowDescriptor.leftRightSelectorLeftOptionSelected isEqual:[self leftOptionForDescription:title].leftValue]){
self.rowDescriptor.value = [self chooseNewRightValueFromOption:[self leftOptionForDescription:title]];
self.rowDescriptor.leftRightSelectorLeftOptionSelected = [self leftOptionForDescription:title].leftValue;
[self.formViewController updateFormRow:self.rowDescriptor];
}
}
}
#endif
@end
+1 -1
View File
@@ -28,6 +28,6 @@
@interface XLFormPickerCell : XLFormBaseCell<XLFormInlineRowDescriptorCell>
@property (nonatomic) UIPickerView * pickerView;
@property (nonatomic, weak) UIPickerView * pickerView;
@end
+8 -12
View File
@@ -56,23 +56,19 @@
return [self formDescriptorCellCanBecomeFirstResponder];
}
#pragma mark - Properties
-(UIPickerView *)pickerView
{
if (_pickerView) return _pickerView;
_pickerView = [UIPickerView autolayoutView];
_pickerView.delegate = self;
_pickerView.dataSource = self;
return _pickerView;
}
#pragma mark - XLFormDescriptorCell
-(void)configure
{
[super configure];
[self.contentView addSubview:self.pickerView];
UIPickerView *pickerView = [UIPickerView autolayoutView];
pickerView.delegate = self;
pickerView.dataSource = self;
[self.contentView addSubview:pickerView];
_pickerView = pickerView;
[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.pickerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[pickerView]-0-|" options:0 metrics:0 views:@{@"pickerView" : self.pickerView}]];
}
+4 -1
View File
@@ -30,7 +30,7 @@
@interface XLFormSegmentedCell()
@property NSMutableArray * dynamicCustomConstraints;
@property (nonatomic, strong) NSMutableArray * dynamicCustomConstraints;
@end
@@ -168,6 +168,9 @@
-(void)dealloc
{
[self.textLabel removeObserver:self forKeyPath:@"text"];
[self.dynamicCustomConstraints removeAllObjects];
self.dynamicCustomConstraints = nil;
}
@end
+96 -176
View File
@@ -29,10 +29,9 @@
#import "XLFormSelectorCell.h"
#import "NSArray+XLFormAdditions.h"
@interface XLFormSelectorCell() <UIActionSheetDelegate, UIPickerViewDelegate, UIPickerViewDataSource, UIPopoverControllerDelegate>
@interface XLFormSelectorCell() <UIPickerViewDelegate, UIPickerViewDataSource, UIPopoverPresentationControllerDelegate>
@property (nonatomic) UIPickerView * pickerView;
@property (nonatomic) UIPopoverController *popoverController;
@end
@@ -87,7 +86,7 @@
return tranformedValue;
}
}
return [self.rowDescriptor.value displayText];
return self.rowDescriptor.displayTextValue;
}
@@ -168,21 +167,28 @@
selectorViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
if (self.popoverController && self.popoverController.popoverVisible) {
[self.popoverController dismissPopoverAnimated:NO];
}
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:selectorViewController];
self.popoverController.delegate = self;
if ([selectorViewController conformsToProtocol:@protocol(XLFormRowDescriptorPopoverViewController)]){
((id<XLFormRowDescriptorPopoverViewController>)selectorViewController).popoverController = self.popoverController;
UIViewController *popoverController = self.formViewController.presentedViewController;
if (popoverController && popoverController.modalPresentationStyle == UIModalPresentationPopover) {
[self.formViewController dismissViewControllerAnimated:NO completion:nil];
}
selectorViewController.modalPresentationStyle = UIModalPresentationPopover;
selectorViewController.popoverPresentationController.delegate = self;
if (self.detailTextLabel.window){
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
selectorViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height);
selectorViewController.popoverPresentationController.sourceView = self.detailTextLabel;
selectorViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
} else {
selectorViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
selectorViewController.popoverPresentationController.sourceView = self;
selectorViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
else{
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
[controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
[self.formViewController presentViewController:selectorViewController
animated:YES
completion:nil];
[controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self]
animated:YES];
}
else {
[controller.navigationController pushViewController:selectorViewController animated:YES];
@@ -194,16 +200,24 @@
optionsViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) {
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
self.popoverController.delegate = self;
optionsViewController.popoverController = self.popoverController;
optionsViewController.modalPresentationStyle = UIModalPresentationPopover;
optionsViewController.popoverPresentationController.delegate = self;
if (self.detailTextLabel.window){
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
optionsViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height);
optionsViewController.popoverPresentationController.sourceView = self.detailTextLabel;
optionsViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
} else {
optionsViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
optionsViewController.popoverPresentationController.sourceView = self;
optionsViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
else{
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
[controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
[self.formViewController presentViewController:optionsViewController
animated:YES
completion:nil];
[controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self]
animated:YES];
} else {
[controller.navigationController pushViewController:optionsViewController animated:YES];
}
@@ -223,126 +237,76 @@
optionsViewController.title = self.rowDescriptor.selectorTitle;
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) {
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController];
self.popoverController.delegate = self;
optionsViewController.popoverController = self.popoverController;
optionsViewController.modalPresentationStyle = UIModalPresentationPopover;
optionsViewController.popoverPresentationController.delegate = self;
if (self.detailTextLabel.window){
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height) inView:self.detailTextLabel permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else{
[self.popoverController presentPopoverFromRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height) inView:self permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
optionsViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.detailTextLabel.frame.size.width, self.detailTextLabel.frame.size.height);
optionsViewController.popoverPresentationController.sourceView = self.detailTextLabel;
optionsViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
} else {
optionsViewController.popoverPresentationController.sourceRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
optionsViewController.popoverPresentationController.sourceView = self;
optionsViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[self.formViewController presentViewController:optionsViewController
animated:YES
completion:nil];
[controller.tableView deselectRowAtIndexPath:[controller.tableView indexPathForCell:self] animated:YES];
} else {
[controller.navigationController pushViewController:optionsViewController animated:YES];
}
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
XLFormViewController * formViewController = self.formViewController;
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
alertController.popoverPresentationController.sourceView = formViewController.tableView;
UIView* v = (self.detailTextLabel ?: self.textLabel) ?: self.contentView;
alertController.popoverPresentationController.sourceRect = [formViewController.tableView convertRect:v.frame fromView:self];
__weak __typeof(self)weakSelf = self;
for (id option in self.rowDescriptor.selectorOptions) {
[actionSheet addButtonWithTitle:[option displayText]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
actionSheet.tag = [self.rowDescriptor hash];
[actionSheet showInView:controller.view];
#else
if ([UIAlertController class]) {
XLFormViewController * formViewController = self.formViewController;
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
alertController.popoverPresentationController.sourceView = formViewController.tableView;
UIView* v = (self.detailTextLabel ?: self.textLabel) ?: self.contentView;
alertController.popoverPresentationController.sourceRect = [formViewController.tableView convertRect:v.frame fromView:self];
__weak __typeof(self)weakSelf = self;
for (id option in self.rowDescriptor.selectorOptions) {
[alertController addAction:[UIAlertAction actionWithTitle:[option displayText]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[weakSelf.rowDescriptor setValue:option];
[formViewController.tableView reloadData];
}]];
NSString *optionTitle = [option displayText];
if (self.rowDescriptor.valueTransformer){
NSAssert([self.rowDescriptor.valueTransformer isSubclassOfClass:[NSValueTransformer class]], @"valueTransformer is not a subclass of NSValueTransformer");
NSValueTransformer * valueTransformer = [self.rowDescriptor.valueTransformer new];
NSString * transformedValue = [valueTransformer transformedValue:[option valueData]];
if (transformedValue) {
optionTitle = transformedValue;
}
}
[formViewController presentViewController:alertController animated:YES completion:nil];
[alertController addAction:[UIAlertAction actionWithTitle:optionTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[weakSelf.rowDescriptor setValue:option];
[formViewController.tableView reloadData];
}]];
}
#ifndef XL_APP_EXTENSIONS
else{
UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (id option in self.rowDescriptor.selectorOptions) {
[actionSheet addButtonWithTitle:[option displayText]];
}
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
actionSheet.tag = [self.rowDescriptor hash];
[actionSheet showInView:controller.view];
}
#endif
#endif
[formViewController presentViewController:alertController animated:YES completion:nil];
[controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorAlertView]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:self.rowDescriptor.selectorTitle
message:nil
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
__weak __typeof(self)weakSelf = self;
for (id option in self.rowDescriptor.selectorOptions) {
[alertView addButtonWithTitle:[option displayText]];
[alertController addAction:[UIAlertAction actionWithTitle:[option displayText]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[weakSelf.rowDescriptor setValue:option];
[weakSelf.formViewController.tableView reloadData];
}]];
}
alertView.cancelButtonIndex = [alertView addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
alertView.tag = [self.rowDescriptor hash];
[alertView show];
#else
if ([UIAlertController class]) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:self.rowDescriptor.selectorTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
__weak __typeof(self)weakSelf = self;
for (id option in self.rowDescriptor.selectorOptions) {
[alertController addAction:[UIAlertAction actionWithTitle:[option displayText]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[weakSelf.rowDescriptor setValue:option];
[weakSelf.formViewController.tableView reloadData];
}]];
}
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
[controller presentViewController:alertController animated:YES completion:nil];
}
#ifndef XL_APP_EXTENSIONS
else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:self.rowDescriptor.selectorTitle
message:nil
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
for (id option in self.rowDescriptor.selectorOptions) {
[alertView addButtonWithTitle:[option displayText]];
}
alertView.cancelButtonIndex = [alertView addButtonWithTitle:NSLocalizedString(@"Cancel", nil)];
alertView.tag = [self.rowDescriptor hash];
[alertView show];
}
#endif
#endif
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleCancel
handler:nil]];
[controller presentViewController:alertController animated:YES completion:nil];
[controller.tableView deselectRowAtIndexPath:[controller.form indexPathOfFormRow:self.rowDescriptor] animated:YES];
}
else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPickerView]){
@@ -363,47 +327,6 @@
self.detailTextLabel.textColor = _beforeChangeColor;
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){
if ([actionSheet cancelButtonIndex] != buttonIndex){
NSString * title = [actionSheet buttonTitleAtIndex:buttonIndex];
for (id option in self.rowDescriptor.selectorOptions){
if ([[option displayText] isEqualToString:title]){
[self.rowDescriptor setValue:option];
[self.formViewController.tableView reloadData];
break;
}
}
}
}
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorAlertView]){
if ([alertView cancelButtonIndex] != buttonIndex){
NSString * title = [alertView buttonTitleAtIndex:buttonIndex];
for (id option in self.rowDescriptor.selectorOptions){
if ([[option displayText] isEqualToString:title]){
[self.rowDescriptor setValue:option];
[self.formViewController.tableView reloadData];
break;
}
}
}
}
}
#endif
#pragma mark - UIPickerViewDelegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
@@ -440,6 +363,11 @@
return self.rowDescriptor.selectorOptions.count;
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
[self.formViewController.tableView reloadData];
}
#pragma mark - Helpers
@@ -484,12 +412,4 @@
return nil;
}
#pragma mark - UIPopoverControllerDelegate
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
[self.formViewController.tableView reloadData];
}
@end
+1 -1
View File
@@ -40,7 +40,7 @@
#pragma mark - XLFormStepCounterCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
+5 -3
View File
@@ -27,12 +27,14 @@
#import <UIKit/UIKit.h>
extern NSString *const XLFormTextFieldLengthPercentage;
extern NSString *const XLFormTextFieldMaxNumberOfCharacters;
@interface XLFormTextFieldCell : XLFormBaseCell <XLFormReturnKeyProtocol>
@property (nonatomic, readonly) UILabel * textLabel;
@property (nonatomic, readonly) UITextField * textField;
@property (nonatomic, readonly, weak) UILabel * textLabel;
@property (nonatomic, readonly, weak) UITextField * textField;
@property (nonatomic) NSNumber *textFieldLengthPercentage;
@property (nonatomic, copy) NSNumber *textFieldLengthPercentage;
@property (nonatomic, copy) NSNumber *textFieldMaxNumberOfCharacters;
@end
+30 -24
View File
@@ -30,10 +30,11 @@
#import "XLFormTextFieldCell.h"
NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
NSString *const XLFormTextFieldMaxNumberOfCharacters = @"textFieldMaxNumberOfCharacters";
@interface XLFormTextFieldCell() <UITextFieldDelegate>
@property NSMutableArray * dynamicCustomConstraints;
@property (nonatomic, strong) NSMutableArray * dynamicCustomConstraints;
@end
@@ -68,8 +69,14 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
-(void)dealloc
{
[self.textField removeTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[self.textLabel removeObserver:self forKeyPath:@"text"];
[self.imageView removeObserver:self forKeyPath:@"image"];
self.textField.delegate = nil;
[self.dynamicCustomConstraints removeAllObjects];
self.dynamicCustomConstraints = nil;
}
#pragma mark - XLFormDescriptorCell
@@ -78,8 +85,14 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
{
[super configure];
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
[self.contentView addSubview:self.textLabel];
[self.contentView addSubview:self.textField];
UILabel *textLabel = [UILabel autolayoutView];
[self.contentView addSubview:textLabel];
_textLabel = textLabel;
UITextField *textField = [UITextField autolayoutView];
[self.contentView addSubview:textField];
_textField = textField;
[self.contentView addConstraints:[self layoutConstraints]];
[self.textLabel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
[self.imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
@@ -175,22 +188,6 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
[self.formViewController updateFormRow:self.rowDescriptor];
}
#pragma mark - Properties
-(UILabel *)textLabel
{
if (_textLabel) return _textLabel;
_textLabel = [UILabel autolayoutView];
return _textLabel;
}
-(UITextField *)textField
{
if (_textField) return _textField;
_textField = [UITextField autolayoutView];
return _textField;
}
#pragma mark - LayoutConstraints
-(NSArray *)layoutConstraints
@@ -224,10 +221,10 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
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
relatedBy:self.textFieldLengthPercentage != nil ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
toItem:self.contentView
attribute:NSLayoutAttributeWidth
multiplier:self.textFieldLengthPercentage ? [self.textFieldLengthPercentage floatValue] : 0.3
multiplier:self.textFieldLengthPercentage != nil ? [self.textFieldLengthPercentage floatValue] : 0.3
constant:0.0]];
}
else{
@@ -239,10 +236,10 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
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
relatedBy:self.textFieldLengthPercentage != nil ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
toItem:self.contentView
attribute:NSLayoutAttributeWidth
multiplier:self.textFieldLengthPercentage ? [self.textFieldLengthPercentage floatValue] : 0.3
multiplier:self.textFieldLengthPercentage != nil ? [self.textFieldLengthPercentage floatValue] : 0.3
constant:0.0]];
}
else{
@@ -278,6 +275,15 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (self.textFieldMaxNumberOfCharacters != nil) {
// Check maximum length requirement
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (newString.length > self.textFieldMaxNumberOfCharacters.integerValue) {
return NO;
}
}
// Otherwise, leave response to view controller
return [self.formViewController textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
@@ -331,7 +337,7 @@ NSString *const XLFormTextFieldLengthPercentage = @"textFieldLengthPercentage";
if (!didUseFormatter)
{
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeNumber] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDecimal]){
self.rowDescriptor.value = [NSDecimalNumber decimalNumberWithString: self.textField.text];
self.rowDescriptor.value = [NSDecimalNumber decimalNumberWithString:self.textField.text locale:NSLocale.currentLocale];
} else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeInteger]){
self.rowDescriptor.value = @([self.textField.text integerValue]);
} else {
+5 -3
View File
@@ -28,13 +28,15 @@
#import <UIKit/UIKit.h>
extern NSString *const XLFormTextViewLengthPercentage;
extern NSString *const XLFormTextViewMaxNumberOfCharacters;
@interface XLFormTextViewCell : XLFormBaseCell
@property (nonatomic, readonly) UILabel * label DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use textLabel instead");
@property (nonatomic, readonly) UILabel * textLabel;
@property (nonatomic, readonly) XLFormTextView * textView;
@property (nonatomic, readonly, weak) UILabel * textLabel;
@property (nonatomic, readonly, weak) XLFormTextView * textView;
@property (nonatomic) NSNumber *textViewLengthPercentage;
@property (nonatomic, copy) NSNumber *textViewLengthPercentage;
@property (nonatomic, copy) NSNumber *textViewMaxNumberOfCharacters;
@end
+20 -19
View File
@@ -29,8 +29,8 @@
#import "XLFormTextView.h"
#import "XLFormTextViewCell.h"
NSString *const kFormTextViewCellPlaceholder = @"placeholder";
NSString *const XLFormTextViewLengthPercentage = @"textViewLengthPercentage";
NSString *const XLFormTextViewMaxNumberOfCharacters = @"textViewMaxNumberOfCharacters";
@interface XLFormTextViewCell() <UITextViewDelegate>
@@ -70,34 +70,26 @@ NSString *const XLFormTextViewLengthPercentage = @"textViewLengthPercentage";
#pragma mark - Properties
-(UILabel *)textLabel
{
if (_textLabel) return _textLabel;
_textLabel = [UILabel autolayoutView];
[_textLabel setContentHuggingPriority:500 forAxis:UILayoutConstraintAxisHorizontal];
return _textLabel;
}
-(UILabel *)label
{
return self.textLabel;
}
-(XLFormTextView *)textView
{
if (_textView) return _textView;
_textView = [XLFormTextView autolayoutView];
return _textView;
}
#pragma mark - XLFormDescriptorCell
-(void)configure
{
[super configure];
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
[self.contentView addSubview:self.textLabel];
[self.contentView addSubview:self.textView];
UILabel *textLabel = [UILabel autolayoutView];
[textLabel setContentHuggingPriority:500 forAxis:UILayoutConstraintAxisHorizontal];
[self.contentView addSubview:textLabel];
_textLabel = textLabel;
XLFormTextView *textView = [XLFormTextView autolayoutView];
[self.contentView addSubview:textView];
_textView = textView;
[self.textLabel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
NSDictionary * views = @{@"label": self.textLabel, @"textView": self.textView};
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[label]" options:0 metrics:0 views:views]];
@@ -160,7 +152,7 @@ NSString *const XLFormTextViewLengthPercentage = @"textViewLengthPercentage";
}
else{
[_dynamicCustomConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-[textView]-|" options:0 metrics:0 views:views]];
if (self.textViewLengthPercentage) {
if (self.textViewLengthPercentage != nil) {
[_dynamicCustomConstraints addObject:[NSLayoutConstraint constraintWithItem:_textView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
@@ -207,6 +199,15 @@ NSString *const XLFormTextViewLengthPercentage = @"textViewLengthPercentage";
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if (self.textViewMaxNumberOfCharacters != nil) {
// Check maximum length requirement
NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
if (newText.length > self.textViewMaxNumberOfCharacters.integerValue) {
return NO;
}
}
// Otherwise, leave response to view controller
return [self.formViewController textView:textView shouldChangeTextInRange:range replacementText:text];
}
@@ -28,6 +28,9 @@
@interface XLFormOptionsObject : NSObject <XLFormOptionObject,NSCoding>
@property (nonatomic, copy) NSString * formDisplaytext;
@property (nonatomic, strong) id formValue;
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText;
+(XLFormOptionsObject *)formOptionsOptionForValue:(id)value fromOptions:(NSArray *)options;
+(XLFormOptionsObject *)formOptionsOptionForDisplayText:(NSString *)displayText fromOptions:(NSArray *)options;
+10 -6
View File
@@ -26,17 +26,13 @@
#import "XLFormOptionsObject.h"
@implementation XLFormOptionsObject
{
NSString * _formDisplaytext;
id _formValue;
}
+(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText
{
return [[XLFormOptionsObject alloc] initWithValue:value displayText:displayText];
}
-(id)initWithValue:(id)value displayText:(NSString *)displayText
-(instancetype)initWithValue:(id)value displayText:(NSString *)displayText
{
self = [super init];
if (self){
@@ -85,6 +81,7 @@
{
return _formValue;
}
#pragma mark - NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder
{
@@ -94,7 +91,8 @@
[encoder encodeObject:self.formDisplayText
forKey:@"formDisplayText"];
}
-(id)initWithCoder:(NSCoder *)decoder
-(instancetype)initWithCoder:(NSCoder *)decoder
{
if ((self=[super init])) {
@@ -108,4 +106,10 @@
return self;
}
-(NSUInteger)hash
{
return [[self formValue ] hash];
}
@end
@@ -28,12 +28,12 @@
#import "XLFormRowDescriptorViewController.h"
#import "XLFormRowDescriptor.h"
@interface XLFormOptionsViewController : UITableViewController<XLFormRowDescriptorViewController, XLFormRowDescriptorPopoverViewController>
@interface XLFormOptionsViewController : UITableViewController<XLFormRowDescriptorViewController>
- (id)initWithStyle:(UITableViewStyle)style;
- (instancetype)initWithStyle:(UITableViewStyle)style;
- (id)initWithStyle:(UITableViewStyle)style
- (instancetype)initWithStyle:(UITableViewStyle)style
titleHeaderSection:(NSString *)titleHeaderSection
titleFooterSection:(NSString *)titleFooterSection;
@@ -34,8 +34,8 @@
@interface XLFormOptionsViewController () <UITableViewDataSource>
@property NSString * titleHeaderSection;
@property NSString * titleFooterSection;
@property (nonatomic, copy) NSString * titleHeaderSection;
@property (nonatomic, copy) NSString * titleFooterSection;
@end
@@ -45,9 +45,8 @@
@synthesize titleHeaderSection = _titleHeaderSection;
@synthesize titleFooterSection = _titleFooterSection;
@synthesize rowDescriptor = _rowDescriptor;
@synthesize popoverController = __popoverController;
- (id)initWithStyle:(UITableViewStyle)style
- (instancetype)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self){
@@ -57,7 +56,7 @@
return self;
}
- (id)initWithStyle:(UITableViewStyle)style titleHeaderSection:(NSString *)titleHeaderSection titleFooterSection:(NSString *)titleFooterSection
- (instancetype)initWithStyle:(UITableViewStyle)style titleHeaderSection:(NSString *)titleHeaderSection titleFooterSection:(NSString *)titleFooterSection
{
self = [self initWithStyle:style];
if (self){
@@ -86,6 +85,11 @@
{
XLFormRightDetailCell * cell = [tableView dequeueReusableCellWithIdentifier:CELL_REUSE_IDENTIFIER forIndexPath:indexPath];
id cellObject = [[self selectorOptions] objectAtIndex:indexPath.row];
[self.rowDescriptor.cellConfigForSelector enumerateKeysAndObjectsUsingBlock:^(NSString *keyPath, id value, __unused BOOL *stop) {
[cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
}];
cell.textLabel.text = [self valueDisplayTextForOption:cellObject];
if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]){
cell.accessoryType = ([self selectedValuesContainsOption:cellObject] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone);
@@ -133,8 +137,8 @@
if ([[self.rowDescriptor.value valueData] isEqual:[cellObject valueData]]){
if (!self.rowDescriptor.required){
self.rowDescriptor.value = nil;
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.accessoryType = UITableViewCellAccessoryNone;
}
else{
if (self.rowDescriptor.value){
@@ -148,9 +152,8 @@
self.rowDescriptor.value = cellObject;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
if (self.popoverController){
[self.popoverController dismissPopoverAnimated:YES];
[self.popoverController.delegate popoverControllerDidDismissPopover:self.popoverController];
if (self.modalPresentationStyle == UIModalPresentationPopover){
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
}
else if ([self.parentViewController isKindOfClass:[UINavigationController class]]){
[self.navigationController popViewControllerAnimated:YES];
@@ -30,14 +30,6 @@
@protocol XLFormRowDescriptorViewController <NSObject>
@required
@property (nonatomic) XLFormRowDescriptor * rowDescriptor;
@end
@protocol XLFormRowDescriptorPopoverViewController <NSObject>
@required
@property (nonatomic) UIPopoverController * popoverController;
@property (nonatomic, weak) XLFormRowDescriptor * rowDescriptor;
@end
+4 -3
View File
@@ -60,6 +60,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;
@@ -78,10 +79,10 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) {
@end
@interface XLFormViewController : UIViewController<UITableViewDataSource, UITableViewDelegate, XLFormDescriptorDelegate, UITextFieldDelegate, UITextViewDelegate, UIActionSheetDelegate, XLFormViewControllerDelegate>
@interface XLFormViewController : UIViewController<UITableViewDataSource, UITableViewDelegate, XLFormDescriptorDelegate, UITextFieldDelegate, UITextViewDelegate, XLFormViewControllerDelegate>
@property XLFormDescriptor * form;
@property IBOutlet UITableView * tableView;
@property (nonatomic, strong) XLFormDescriptor * form;
@property (nonatomic, weak) IBOutlet UITableView * tableView;
-(instancetype)initWithForm:(XLFormDescriptor *)form;
-(instancetype)initWithForm:(XLFormDescriptor *)form style:(UITableViewStyle)style;
+100 -89
View File
@@ -33,7 +33,6 @@
@interface XLFormRowDescriptor(_XLFormViewController)
@property (readonly) NSArray * observers;
-(BOOL)evaluateIsDisabled;
-(BOOL)evaluateIsHidden;
@@ -47,7 +46,7 @@
@interface XLFormDescriptor (_XLFormViewController)
@property NSMutableDictionary* rowObservers;
@property (atomic, strong) NSMutableDictionary* rowObservers;
@end
@@ -57,8 +56,8 @@
NSNumber *_oldBottomTableContentInset;
CGRect _keyboardFrame;
}
@property UITableViewStyle tableViewStyle;
@property (nonatomic) XLFormRowNavigationAccessoryView * navigationAccessoryView;
@property (nonatomic, assign) UITableViewStyle tableViewStyle;
@property (nonatomic, strong) XLFormRowNavigationAccessoryView * navigationAccessoryView;
@end
@@ -68,12 +67,12 @@
#pragma mark - Initialization
-(id)initWithForm:(XLFormDescriptor *)form
-(instancetype)initWithForm:(XLFormDescriptor *)form
{
return [self initWithForm:form style:UITableViewStyleGrouped];
}
-(id)initWithForm:(XLFormDescriptor *)form style:(UITableViewStyle)style
-(instancetype)initWithForm:(XLFormDescriptor *)form style:(UITableViewStyle)style
{
self = [self initWithNibName:nil bundle:nil];
if (self){
@@ -104,25 +103,34 @@
return self;
}
- (void)dealloc
-(void)dealloc
{
[self removeObserverFromController];
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.form.delegate = nil;
self.navigationAccessoryView = nil;
}
- (void)viewDidLoad
-(void)viewDidLoad
{
[super viewDidLoad];
if (!self.tableView){
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds
UITableView *tableView = self.tableView;
if (!tableView){
tableView = [[UITableView alloc] initWithFrame:self.view.bounds
style:self.tableViewStyle];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
if([self.tableView respondsToSelector:@selector(cellLayoutMarginsFollowReadableWidth)]){
self.tableView.cellLayoutMarginsFollowReadableWidth = NO;
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
if([tableView respondsToSelector:@selector(cellLayoutMarginsFollowReadableWidth)]){
tableView.cellLayoutMarginsFollowReadableWidth = NO;
}
}
if (!self.tableView.superview){
[self.view addSubview:self.tableView];
if (!tableView.superview){
[self.view addSubview:tableView];
self.tableView = tableView;
}
if (!self.tableView.delegate){
self.tableView.delegate = self;
@@ -147,44 +155,18 @@
{
[super viewWillAppear:animated];
NSIndexPath *selected = [self.tableView indexPathForSelectedRow];
if (selected){
if (selected) {
// Trigger a cell refresh
XLFormRowDescriptor * rowDescriptor = [self.form formRowAtIndex:selected];
[self updateFormRow:rowDescriptor];
[self.tableView selectRowAtIndexPath:selected animated:NO scrollPosition:UITableViewScrollPositionNone];
[self.tableView deselectRowAtIndexPath:selected animated:YES];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeCategoryChanged:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[self addObserverToController];
}
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIContentSizeCategoryDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewDidAppear:(BOOL)animated
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.form.assignFirstResponderOnShow) {
@@ -193,11 +175,40 @@
}
}
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self removeObserverFromController];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)addObserverToController {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(contentSizeCategoryChanged:)
name:UIContentSizeCategoryDidChangeNotification
object:nil];
[nc addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[nc addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
-(void)removeObserverFromController {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark - CellClasses
+(NSMutableDictionary *)cellClassesForRowDescriptorTypes
@@ -314,8 +325,8 @@
-(void)updateAfterDependentRowChanged:(XLFormRowDescriptor *)formRow
{
NSMutableArray* revaluateHidden = self.form.rowObservers[[formRow.tag formKeyForPredicateType:XLPredicateTypeHidden]];
NSMutableArray* revaluateDisabled = self.form.rowObservers[[formRow.tag formKeyForPredicateType:XLPredicateTypeDisabled]];
NSMutableArray* revaluateHidden = [self.form.rowObservers[[formRow.tag formKeyForPredicateType:XLPredicateTypeHidden]] mutableCopy];
NSMutableArray* revaluateDisabled = [self.form.rowObservers[[formRow.tag formKeyForPredicateType:XLPredicateTypeDisabled]] mutableCopy];
for (id object in revaluateDisabled) {
if ([object isKindOfClass:[NSString class]]) {
XLFormRowDescriptor* row = [self.form formRowWithTag:object];
@@ -434,9 +445,10 @@
XLFormSectionDescriptor * multivaluedFormSection = formRow.sectionDescriptor;
XLFormRowDescriptor * formRowDescriptor = [self formRowFormMultivaluedFormSection:multivaluedFormSection];
[multivaluedFormSection addFormRow:formRowDescriptor];
__weak typeof(self) weak = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.02 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tableView.editing = !self.tableView.editing;
self.tableView.editing = !self.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
});
UITableViewCell<XLFormDescriptorCell> * cell = (UITableViewCell<XLFormDescriptorCell> *)[formRowDescriptor cellForFormController:self];
if ([cell formDescriptorCellCanBecomeFirstResponder]){
@@ -462,34 +474,24 @@
-(void)showFormValidationError:(NSError *)error
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"XLFormViewController_ValidationErrorTitle", nil)
message:error.localizedDescription
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[alertView show];
#else
if ([UIAlertController class]){
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"XLFormViewController_ValidationErrorTitle", 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(@"XLFormViewController_ValidationErrorTitle", nil)
message:error.localizedDescription
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[alertView show];
}
#endif
#endif
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"XLFormViewController_ValidationErrorTitle", nil)
message:error.localizedDescription
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
}
-(void)showFormValidationError:(NSError *)error withTitle:(NSString*)title
{
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];
}
-(void)performFormSelector:(SEL)selector withObject:(id)sender
@@ -578,18 +580,24 @@
-(XLFormBaseCell *)updateFormRow:(XLFormRowDescriptor *)formRow
{
XLFormBaseCell * cell = [formRow cellForFormController:self];
[self configureCell:cell];
[cell setNeedsUpdateConstraints];
[cell setNeedsLayout];
if (cell != nil) {
[self configureCell:cell];
[cell setNeedsUpdateConstraints];
[cell setNeedsLayout];
}
return cell;
}
-(void)configureCell:(XLFormBaseCell*) cell
{
[cell update];
[cell.rowDescriptor.cellConfig enumerateKeysAndObjectsUsingBlock:^(NSString *keyPath, id value, BOOL * __unused stop) {
[cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
}];
if(cell.rowDescriptor != nil && cell.rowDescriptor.cellConfig != nil) {
[cell.rowDescriptor.cellConfig enumerateKeysAndObjectsUsingBlock:^(NSString *keyPath, id value, BOOL * __unused stop) {
[cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
}];
}
if (cell.rowDescriptor.isDisabled){
[cell.rowDescriptor.cellConfigIfDisabled enumerateKeysAndObjectsUsingBlock:^(NSString *keyPath, id value, BOOL * __unused stop) {
[cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
@@ -660,9 +668,10 @@
#pragma GCC diagnostic pop
// update the accessory view
[self inputAccessoryViewForRowDescriptor:row];
__weak typeof(self) weak = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tableView.editing = !self.tableView.editing;
self.tableView.editing = !self.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
});
}
@@ -677,9 +686,10 @@
[self.tableView endEditing:YES];
}
[multivaluedFormRow.sectionDescriptor removeFormRowAtIndex:indexPath.row];
__weak typeof(self) weak = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.02 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tableView.editing = !self.tableView.editing;
self.tableView.editing = !self.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
});
if (firstResponder){
UITableViewCell<XLFormDescriptorCell> * firstResponderCell = [firstResponder formDescriptorCell];
@@ -696,9 +706,10 @@
else{
XLFormRowDescriptor * formRowDescriptor = [self formRowFormMultivaluedFormSection:multivaluedFormSection];
[multivaluedFormSection addFormRow:formRowDescriptor];
__weak typeof(self) weak = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.02 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.tableView.editing = !self.tableView.editing;
self.tableView.editing = !self.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
weak.tableView.editing = !weak.tableView.editing;
});
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
UITableViewCell<XLFormDescriptorCell> * cell = (UITableViewCell<XLFormDescriptorCell> *)[formRowDescriptor cellForFormController:self];
+8 -8
View File
@@ -49,15 +49,15 @@ typedef NS_OPTIONS(NSUInteger, XLFormRowNavigationOptions) {
@interface XLFormDescriptor : NSObject
@property (readonly, nonatomic, nonnull) NSMutableArray * formSections;
@property (readonly, nullable) NSString * title;
@property (nonatomic) BOOL endEditingTableViewOnScroll;
@property (nonatomic) BOOL assignFirstResponderOnShow;
@property (nonatomic) BOOL addAsteriskToRequiredRowsTitle;
@property (getter=isDisabled) BOOL disabled;
@property (nonatomic) XLFormRowNavigationOptions rowNavigationOptions;
@property (nonatomic, strong, readonly, nonnull) NSMutableArray * formSections;
@property (nonatomic, readonly, nullable, copy) NSString * title;
@property (nonatomic, assign) BOOL endEditingTableViewOnScroll;
@property (nonatomic, assign) BOOL assignFirstResponderOnShow;
@property (nonatomic, assign) BOOL addAsteriskToRequiredRowsTitle;
@property (nonatomic, getter=isDisabled, assign) BOOL disabled;
@property (nonatomic, assign) XLFormRowNavigationOptions rowNavigationOptions;
@property (weak, nullable) id<XLFormDescriptorDelegate> delegate;
@property (nonatomic, weak, nullable) id<XLFormDescriptorDelegate> delegate;
+(nonnull instancetype)formDescriptor;
+(nonnull instancetype)formDescriptorWithTitle:(nullable NSString *)title;
+204 -153
View File
@@ -32,10 +32,13 @@
NSString * const XLFormErrorDomain = @"XLFormErrorDomain";
NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
NSString * const XLFormSectionsKey = @"formSections";
@interface XLFormSectionDescriptor (_XLFormDescriptor)
@property NSArray * allRows;
@property (nonatomic, weak) NSArray *allRows;
-(BOOL)evaluateIsHidden;
@end
@@ -51,11 +54,11 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
@interface XLFormDescriptor()
@property NSMutableArray * formSections;
@property (readonly) NSMutableArray * allSections;
@property NSString * title;
@property (readonly) NSMutableDictionary* allRowsByTag;
@property NSMutableDictionary* rowObservers;
@property (nonatomic, strong) NSMutableArray *formSections;
@property (nonatomic, strong, readonly) NSMutableArray *allSections;
@property (nonatomic, copy ) NSString *title;
@property (nonatomic, strong, readonly) NSMutableDictionary *allRowsByTag;
@property (atomic , strong) NSMutableDictionary *rowObservers;
@end
@@ -63,15 +66,14 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(instancetype)init
{
return [self initWithTitle:nil];
return [self initWithTitle:@""];
}
-(instancetype)initWithTitle:(NSString *)title;
{
self = [super init];
if (self){
if (self = [super init]) {
_formSections = [NSMutableArray array];
_allSections = [NSMutableArray array];
_allSections = [NSMutableArray array];
_allRowsByTag = [NSMutableDictionary dictionary];
_rowObservers = [NSMutableDictionary dictionary];
_title = title;
@@ -79,14 +81,19 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
_disabled = NO;
_endEditingTableViewOnScroll = YES;
_rowNavigationOptions = XLFormRowNavigationOptionEnabled;
[self addObserver:self forKeyPath:@"formSections" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:0];
[self addObserver:self
forKeyPath:XLFormSectionsKey
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:0];
}
return self;
}
+(instancetype)formDescriptor
{
return [[self class] formDescriptorWithTitle:nil];
return [[self class] formDescriptorWithTitle:@""];
}
+(instancetype)formDescriptorWithTitle:(NSString *)title
@@ -101,11 +108,11 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(void)addFormSection:(XLFormSectionDescriptor *)formSection atIndex:(NSUInteger)index
{
if (index == 0){
if (index == 0) {
[self insertObject:formSection inAllSectionsAtIndex:0];
}
else{
XLFormSectionDescriptor* previousSection = [self.formSections objectAtIndex:MIN(self.formSections.count, index-1)];
else {
XLFormSectionDescriptor *previousSection = [self.formSections objectAtIndex:MIN(self.formSections.count, index-1)];
[self addFormSection:formSection afterSection:previousSection];
}
}
@@ -114,26 +121,28 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
{
NSUInteger sectionIndex;
NSUInteger allSectionIndex;
if ((sectionIndex = [self.allSections indexOfObject:formSection]) == NSNotFound){
if ((sectionIndex = [self.allSections indexOfObject:formSection]) == NSNotFound) {
allSectionIndex = [self.allSections indexOfObject:afterSection];
if (allSectionIndex != NSNotFound) {
[self insertObject:formSection inAllSectionsAtIndex:(allSectionIndex + 1)];
}
else { //case when afterSection does not exist. Just insert at the end.
[self addFormSection:formSection];
return;
}
}
formSection.hidden = formSection.hidden;
}
-(void)addFormRow:(XLFormRowDescriptor *)formRow beforeRow:(XLFormRowDescriptor *)beforeRow
{
if (beforeRow.sectionDescriptor){
if (beforeRow.sectionDescriptor) {
[beforeRow.sectionDescriptor addFormRow:formRow beforeRow:beforeRow];
}
else{
else {
[[self.allSections lastObject] addFormRow:formRow beforeRow:beforeRow];
}
}
@@ -144,27 +153,25 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
[self addFormRow:formRow beforeRow:beforeRowForm];
}
-(void)addFormRow:(XLFormRowDescriptor *)formRow afterRow:(XLFormRowDescriptor *)afterRow
{
if (afterRow.sectionDescriptor){
if (afterRow.sectionDescriptor) {
[afterRow.sectionDescriptor addFormRow:formRow afterRow:afterRow];
}
else{
else {
[[self.allSections lastObject] addFormRow:formRow afterRow:afterRow];
}
}
-(void)addFormRow:(XLFormRowDescriptor *)formRow afterRowTag:(NSString *)afterRowTag
{
XLFormRowDescriptor * afterRowForm = [self formRowWithTag:afterRowTag];
XLFormRowDescriptor *afterRowForm = [self formRowWithTag:afterRowTag];
[self addFormRow:formRow afterRow:afterRowForm];
}
-(void)removeFormSectionAtIndex:(NSUInteger)index
{
if (self.formSections.count > index){
if (self.formSections.count > index) {
XLFormSectionDescriptor *formSection = [self.formSections objectAtIndex:index];
[self removeObjectFromFormSectionsAtIndex:index];
NSUInteger allSectionIndex = [self.allSections indexOfObject:formSection];
@@ -175,43 +182,47 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(void)removeFormSection:(XLFormSectionDescriptor *)formSection
{
NSUInteger index = NSNotFound;
if ((index = [self.formSections indexOfObject:formSection]) != NSNotFound){
if ((index = [self.formSections indexOfObject:formSection]) != NSNotFound) {
[self removeFormSectionAtIndex:index];
}
else if ((index = [self.allSections indexOfObject:formSection]) != NSNotFound){
if ((index = [self.allSections indexOfObject:formSection]) != NSNotFound) {
[self removeObjectFromAllSectionsAtIndex:index];
};
}
}
-(void)removeFormRow:(XLFormRowDescriptor *)formRow
{
for (XLFormSectionDescriptor * section in self.formSections){
if ([section.formRows containsObject:formRow]){
for (XLFormSectionDescriptor *section in self.formSections) {
if ([section.formRows containsObject:formRow]) {
[section removeFormRow:formRow];
break;
}
}
}
-(void)showFormSection:(XLFormSectionDescriptor*)formSection
-(void)showFormSection:(XLFormSectionDescriptor *)formSection
{
NSUInteger formIndex = [self.formSections indexOfObject:formSection];
if (formIndex != NSNotFound) {
return;
}
NSUInteger index = [self.allSections indexOfObject:formSection];
if (index != NSNotFound){
if (index != NSNotFound) {
while (formIndex == NSNotFound && index > 0) {
XLFormSectionDescriptor* previous = [self.allSections objectAtIndex:--index];
formIndex = [self.formSections indexOfObject:previous];
}
[self insertObject:formSection inFormSectionsAtIndex:(formIndex == NSNotFound ? 0 : ++formIndex)];
}
}
-(void)hideFormSection:(XLFormSectionDescriptor*)formSection
-(void)hideFormSection:(XLFormSectionDescriptor *)formSection
{
NSUInteger index = [self.formSections indexOfObject:formSection];
if (index != NSNotFound){
if (index != NSNotFound) {
[self removeObjectFromFormSectionsAtIndex:index];
}
}
@@ -224,28 +235,29 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(XLFormRowDescriptor *)formRowWithHash:(NSUInteger)hash
{
for (XLFormSectionDescriptor * section in self.allSections){
for (XLFormRowDescriptor * row in section.allRows) {
if ([row hash] == hash){
for (XLFormSectionDescriptor *section in self.allSections) {
for (XLFormRowDescriptor *row in section.allRows) {
if ([row hash] == hash) {
return row;
}
}
}
return nil;
}
-(void)removeFormRowWithTag:(NSString *)tag
{
XLFormRowDescriptor * formRow = [self formRowWithTag:tag];
XLFormRowDescriptor *formRow = [self formRowWithTag:tag];
[self removeFormRow:formRow];
}
-(XLFormRowDescriptor *)formRowAtIndex:(NSIndexPath *)indexPath
{
if ((self.formSections.count > indexPath.section) && [[self.formSections objectAtIndex:indexPath.section] formRows].count > indexPath.row){
if ((self.formSections.count > indexPath.section) && [[self.formSections objectAtIndex:indexPath.section] formRows].count > indexPath.row) {
return [[[self.formSections objectAtIndex:indexPath.section] formRows] objectAtIndex:indexPath.row];
}
return nil;
}
@@ -256,55 +268,62 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(NSIndexPath *)indexPathOfFormRow:(XLFormRowDescriptor *)formRow
{
XLFormSectionDescriptor * section = formRow.sectionDescriptor;
if (section){
NSIndexPath *result = nil;
XLFormSectionDescriptor *section = formRow.sectionDescriptor;
if (section) {
NSUInteger sectionIndex = [self.formSections indexOfObject:section];
if (sectionIndex != NSNotFound){
if (sectionIndex != NSNotFound) {
NSUInteger rowIndex = [section.formRows indexOfObject:formRow];
if (rowIndex != NSNotFound){
return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
if (rowIndex != NSNotFound) {
result = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
}
}
}
return nil;
return result;
}
-(NSIndexPath *)globalIndexPathOfFormRow:(XLFormRowDescriptor *)formRow
{
XLFormSectionDescriptor * section = formRow.sectionDescriptor;
if (section){
NSIndexPath *result = nil;
XLFormSectionDescriptor *section = formRow.sectionDescriptor;
if (section) {
NSUInteger sectionIndex = [self.allSections indexOfObject:section];
if (sectionIndex != NSNotFound){
if (sectionIndex != NSNotFound) {
NSUInteger rowIndex = [section.allRows indexOfObject:formRow];
if (rowIndex != NSNotFound){
return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
if (rowIndex != NSNotFound) {
result = [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
}
}
}
return nil;
return result;
}
-(NSDictionary *)formValues
{
NSMutableDictionary * result = [NSMutableDictionary dictionary];
for (XLFormSectionDescriptor * section in self.formSections) {
if (section.multivaluedTag.length > 0){
NSMutableArray * multiValuedValuesArray = [NSMutableArray new];
for (XLFormRowDescriptor * row in section.formRows) {
if (row.value){
NSMutableDictionary *result = [NSMutableDictionary dictionary];
for (XLFormSectionDescriptor *section in self.formSections) {
if (section.multivaluedTag.length > 0) {
NSMutableArray *multiValuedValuesArray = [NSMutableArray new];
for (XLFormRowDescriptor *row in section.formRows) {
if (row.value && row.value != [NSNull null]) {
[multiValuedValuesArray addObject:row.value];
}
}
[result setObject:multiValuedValuesArray forKey:section.multivaluedTag];
}
else{
for (XLFormRowDescriptor * row in section.formRows) {
if (row.tag.length > 0){
[result setObject:(row.value ?: [NSNull null]) forKey:row.tag];
else {
for (XLFormRowDescriptor *row in section.formRows) {
id value = [row.value valueData];
if (row.tag.length > 0 && value != nil) {
[result setObject:value forKey:row.tag];
}
}
}
}
return result;
}
@@ -312,49 +331,55 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
{
NSMutableDictionary * result = [NSMutableDictionary dictionary];
for (XLFormSectionDescriptor * section in self.formSections) {
if (section.multivaluedTag.length > 0){
NSMutableArray * multiValuedValuesArray = [NSMutableArray new];
if (section.multivaluedTag.length > 0) {
NSMutableArray *multiValuedValuesArray = [NSMutableArray new];
for (XLFormRowDescriptor * row in section.formRows) {
if ([row.value valueData]){
if ([row.value valueData]) {
[multiValuedValuesArray addObject:[row.value valueData]];
}
}
[result setObject:multiValuedValuesArray forKey:section.multivaluedTag];
}
else{
else {
for (XLFormRowDescriptor * row in section.formRows) {
NSString * httpParameterKey = nil;
if ((httpParameterKey = [self httpParameterKeyForRow:row cell:[row cellForFormController:formViewController]])){
NSString *httpParameterKey = nil;
if ((httpParameterKey = [self httpParameterKeyForRow:row cell:[row cellForFormController:formViewController]])) {
id parameterValue = [row.value valueData] ?: [NSNull null];
[result setObject:parameterValue forKey:httpParameterKey];
}
}
}
}
return result;
}
-(NSString *)httpParameterKeyForRow:(XLFormRowDescriptor *)row cell:(UITableViewCell<XLFormDescriptorCell> *)descriptorCell
{
if ([descriptorCell respondsToSelector:@selector(formDescriptorHttpParameterName)]){
return [descriptorCell formDescriptorHttpParameterName];
NSString *result = nil;
if ([descriptorCell respondsToSelector:@selector(formDescriptorHttpParameterName)]) {
result = [descriptorCell formDescriptorHttpParameterName];
}
if (row.tag.length > 0){
return row.tag;
else if (row.tag.length > 0) {
result = row.tag;
}
return nil;
return result;
}
-(NSArray *)localValidationErrors:(XLFormViewController *)formViewController {
NSMutableArray * result = [NSMutableArray array];
for (XLFormSectionDescriptor * section in self.formSections) {
for (XLFormRowDescriptor * row in section.formRows) {
XLFormValidationStatus* status = [row doValidation];
-(NSArray *)localValidationErrors:(XLFormViewController *)formViewController
{
NSMutableArray *result = [NSMutableArray array];
for (XLFormSectionDescriptor *section in self.formSections) {
for (XLFormRowDescriptor *row in section.formRows) {
XLFormValidationStatus *status = [row doValidation];
if (status != nil && (![status isValid])) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: status.msg,
XLValidationStatusErrorKey: status };
NSError * error = [[NSError alloc] initWithDomain:XLFormErrorDomain code:XLFormErrorCodeGen userInfo:userInfo];
if (error){
NSError *error = [[NSError alloc] initWithDomain:XLFormErrorDomain code:XLFormErrorCodeGen userInfo:userInfo];
if (error) {
[result addObject:error];
}
}
@@ -367,11 +392,11 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
- (void)setFirstResponder:(XLFormViewController *)formViewController
{
for (XLFormSectionDescriptor * formSection in self.formSections) {
for (XLFormRowDescriptor * row in formSection.formRows) {
UITableViewCell<XLFormDescriptorCell> * cell = [row cellForFormController:formViewController];
if ([cell formDescriptorCellCanBecomeFirstResponder]){
if ([cell formDescriptorCellBecomeFirstResponder]){
for (XLFormSectionDescriptor *formSection in self.formSections) {
for (XLFormRowDescriptor *row in formSection.formRows) {
UITableViewCell<XLFormDescriptorCell> *cell = [row cellForFormController:formViewController];
if ([cell formDescriptorCellCanBecomeFirstResponder]) {
if ([cell formDescriptorCellBecomeFirstResponder]) {
return;
}
}
@@ -382,18 +407,23 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- (void)observeValueForKeyPath:(nullable NSString *)keyPath
ofObject:(nullable id)object
change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change
context:(nullable void *)context
{
if (!self.delegate) return;
if ([keyPath isEqualToString:@"formSections"]){
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeInsertion)]){
NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormSectionDescriptor * section = [self.formSections objectAtIndex:indexSet.firstIndex];
if (!self.delegate) {
return;
}
else if ([keyPath isEqualToString:XLFormSectionsKey]) {
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeInsertion)]) {
NSIndexSet *indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormSectionDescriptor *section = [self.formSections objectAtIndex:indexSet.firstIndex];
[self.delegate formSectionHasBeenAdded:section atIndex:indexSet.firstIndex];
}
else if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeRemoval)]){
NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormSectionDescriptor * removedSection = [[change objectForKey:NSKeyValueChangeOldKey] objectAtIndex:0];
else if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeRemoval)]) {
NSIndexSet *indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormSectionDescriptor *removedSection = [[change objectForKey:NSKeyValueChangeOldKey] objectAtIndex:0];
[self.delegate formSectionHasBeenRemoved:removedSection atIndex:indexSet.firstIndex];
}
}
@@ -401,10 +431,16 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(void)dealloc
{
@try {
[self removeObserver:self forKeyPath:@"formSections"];
}
@catch (NSException * __unused exception) {}
[self removeObserver:self forKeyPath:XLFormSectionsKey];
[_formSections removeAllObjects];
_formSections = nil;
[_allSections removeAllObjects];
_allSections = nil;
[_allRowsByTag removeAllObjects];
_allRowsByTag = nil;
[_rowObservers removeAllObjects];
_rowObservers = nil;
}
#pragma mark - KVC
@@ -414,19 +450,23 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
return self.formSections.count;
}
- (id)objectInFormSectionsAtIndex:(NSUInteger)index {
- (id)objectInFormSectionsAtIndex:(NSUInteger)index
{
return [self.formSections objectAtIndex:index];
}
- (NSArray *)formSectionsAtIndexes:(NSIndexSet *)indexes {
- (NSArray *)formSectionsAtIndexes:(NSIndexSet *)indexes
{
return [self.formSections objectsAtIndexes:indexes];
}
- (void)insertObject:(XLFormSectionDescriptor *)formSection inFormSectionsAtIndex:(NSUInteger)index {
- (void)insertObject:(XLFormSectionDescriptor *)formSection inFormSectionsAtIndex:(NSUInteger)index
{
[self.formSections insertObject:formSection atIndex:index];
}
- (void)removeObjectFromFormSectionsAtIndex:(NSUInteger)index {
- (void)removeObjectFromFormSectionsAtIndex:(NSUInteger)index
{
[self.formSections removeObjectAtIndex:index];
}
@@ -445,7 +485,8 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
return [self.allSections objectsAtIndexes:indexes];
}
- (void)removeObjectFromAllSectionsAtIndex:(NSUInteger)index {
- (void)removeObjectFromAllSectionsAtIndex:(NSUInteger)index
{
XLFormSectionDescriptor* section = [self.allSections objectAtIndex:index];
[section.allRows enumerateObjectsUsingBlock:^(id obj, NSUInteger __unused idx, BOOL *stop) {
XLFormRowDescriptor * row = (id)obj;
@@ -456,7 +497,8 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
[self.allSections removeObjectAtIndex:index];
}
- (void)insertObject:(XLFormSectionDescriptor *)section inAllSectionsAtIndex:(NSUInteger)index {
- (void)insertObject:(XLFormSectionDescriptor *)section inAllSectionsAtIndex:(NSUInteger)index
{
section.formDescriptor = self;
[self.allSections insertObject:section atIndex:index];
section.hidden = section.hidden;
@@ -466,24 +508,23 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
row.hidden = row.hidden;
row.disabled = row.disabled;
}];
}
#pragma mark - EvaluateForm
-(void)forceEvaluate
{
for (XLFormSectionDescriptor* section in self.allSections){
for (XLFormRowDescriptor* row in section.allRows) {
for (XLFormSectionDescriptor *section in self.allSections) {
for (XLFormRowDescriptor *row in section.allRows) {
[self addRowToTagCollection:row];
}
}
for (XLFormSectionDescriptor* section in self.allSections){
for (XLFormRowDescriptor* row in section.allRows) {
for (XLFormSectionDescriptor *section in self.allSections) {
for (XLFormRowDescriptor *row in section.allRows) {
[row evaluateIsDisabled];
[row evaluateIsHidden];
}
[section evaluateIsHidden];
}
}
@@ -500,60 +541,65 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(XLFormRowDescriptor *)nextRowDescriptorForRow:(XLFormRowDescriptor *)row
{
XLFormRowDescriptor *result = nil;
NSUInteger indexOfRow = [row.sectionDescriptor.formRows indexOfObject:row];
if (indexOfRow != NSNotFound){
if (indexOfRow + 1 < row.sectionDescriptor.formRows.count){
return [row.sectionDescriptor.formRows objectAtIndex:++indexOfRow];
if (indexOfRow != NSNotFound) {
if (indexOfRow + 1 < row.sectionDescriptor.formRows.count) {
result = [row.sectionDescriptor.formRows objectAtIndex:++indexOfRow];
}
else{
else {
NSUInteger sectionIndex = [self.formSections indexOfObject:row.sectionDescriptor];
NSUInteger numberOfSections = [self.formSections count];
if (sectionIndex != NSNotFound && sectionIndex < numberOfSections - 1){
if (sectionIndex != NSNotFound && sectionIndex < numberOfSections - 1) {
sectionIndex++;
XLFormSectionDescriptor * sectionDescriptor;
while ([[(sectionDescriptor = [row.sectionDescriptor.formDescriptor.formSections objectAtIndex:sectionIndex]) formRows] count] == 0 && sectionIndex < numberOfSections - 1){
XLFormSectionDescriptor *sectionDescriptor;
while ([[(sectionDescriptor = [row.sectionDescriptor.formDescriptor.formSections objectAtIndex:sectionIndex]) formRows] count] == 0 && sectionIndex < numberOfSections - 1) {
sectionIndex++;
}
return [sectionDescriptor.formRows firstObject];
result = [sectionDescriptor.formRows firstObject];
}
}
}
return nil;
return result;
}
-(XLFormRowDescriptor *)previousRowDescriptorForRow:(XLFormRowDescriptor *)row
{
XLFormRowDescriptor *result = nil;
NSUInteger indexOfRow = [row.sectionDescriptor.formRows indexOfObject:row];
if (indexOfRow != NSNotFound){
if (indexOfRow > 0 ){
return [row.sectionDescriptor.formRows objectAtIndex:--indexOfRow];
if (indexOfRow != NSNotFound) {
if (indexOfRow > 0 ) {
result = [row.sectionDescriptor.formRows objectAtIndex:--indexOfRow];
}
else{
else {
NSUInteger sectionIndex = [self.formSections indexOfObject:row.sectionDescriptor];
if (sectionIndex != NSNotFound && sectionIndex > 0){
if (sectionIndex != NSNotFound && sectionIndex > 0) {
sectionIndex--;
XLFormSectionDescriptor * sectionDescriptor;
while ([[(sectionDescriptor = [row.sectionDescriptor.formDescriptor.formSections objectAtIndex:sectionIndex]) formRows] count] == 0 && sectionIndex > 0 ){
while ([[(sectionDescriptor = [row.sectionDescriptor.formDescriptor.formSections objectAtIndex:sectionIndex]) formRows] count] == 0 && sectionIndex > 0 ) {
sectionIndex--;
}
return [sectionDescriptor.formRows lastObject];
result = [sectionDescriptor.formRows lastObject];
}
}
}
return nil;
return result;
}
-(void)addRowToTagCollection:(XLFormRowDescriptor*) rowDescriptor
-(void)addRowToTagCollection:(XLFormRowDescriptor *)rowDescriptor
{
if (rowDescriptor.tag) {
if (rowDescriptor.tag.length) {
self.allRowsByTag[rowDescriptor.tag] = rowDescriptor;
}
}
-(void)removeRowFromTagCollection:(XLFormRowDescriptor *)rowDescriptor
{
if (rowDescriptor.tag){
if (rowDescriptor.tag.length) {
[self.allRowsByTag removeObjectForKey:rowDescriptor.tag];
}
}
@@ -561,32 +607,36 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(void)addObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType
{
NSPredicate* predicate;
NSPredicate *predicate;
id descriptor;
switch(predicateType){
switch (predicateType) {
case XLPredicateTypeHidden:
if ([sectionOrRow isKindOfClass:([XLFormRowDescriptor class])]) {
descriptor = ((XLFormRowDescriptor*)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor*)sectionOrRow).hidden;
descriptor = ((XLFormRowDescriptor *)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor *)sectionOrRow).hidden;
}
else if ([sectionOrRow isKindOfClass:([XLFormSectionDescriptor class])]) {
descriptor = sectionOrRow;
predicate = ((XLFormSectionDescriptor*)sectionOrRow).hidden;
predicate = ((XLFormSectionDescriptor *)sectionOrRow).hidden;
}
break;
case XLPredicateTypeDisabled:
if ([sectionOrRow isKindOfClass:([XLFormRowDescriptor class])]) {
descriptor = ((XLFormRowDescriptor*)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor*)sectionOrRow).disabled;
descriptor = ((XLFormRowDescriptor *)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor *)sectionOrRow).disabled;
}
else {
return;
}
else return;
break;
}
NSMutableArray* tags = [predicate getPredicateVars];
for (NSString* tag in tags) {
NSString* auxTag = [tag formKeyForPredicateType:predicateType];
if (!self.rowObservers[auxTag]){
NSMutableArray *tags = [predicate getPredicateVars];
for (NSString *tag in tags) {
NSString *auxTag = [tag formKeyForPredicateType:predicateType];
if (!self.rowObservers[auxTag]) {
self.rowObservers[auxTag] = [NSMutableArray array];
}
if (![self.rowObservers[auxTag] containsObject:descriptor])
@@ -597,31 +647,32 @@ NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey";
-(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType
{
NSPredicate* predicate;
NSPredicate *predicate;
id descriptor;
switch(predicateType){
switch(predicateType) {
case XLPredicateTypeHidden:
if ([sectionOrRow isKindOfClass:([XLFormRowDescriptor class])]) {
descriptor = ((XLFormRowDescriptor*)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor*)sectionOrRow).hidden;
descriptor = ((XLFormRowDescriptor *)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor *)sectionOrRow).hidden;
}
else if ([sectionOrRow isKindOfClass:([XLFormSectionDescriptor class])]) {
descriptor = sectionOrRow;
predicate = ((XLFormSectionDescriptor*)sectionOrRow).hidden;
predicate = ((XLFormSectionDescriptor *)sectionOrRow).hidden;
}
break;
case XLPredicateTypeDisabled:
if ([sectionOrRow isKindOfClass:([XLFormRowDescriptor class])]) {
descriptor = ((XLFormRowDescriptor*)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor*)sectionOrRow).disabled;
descriptor = ((XLFormRowDescriptor *)sectionOrRow).tag;
predicate = ((XLFormRowDescriptor *)sectionOrRow).disabled;
}
break;
}
if (descriptor && [predicate isKindOfClass:[NSPredicate class] ]) {
NSMutableArray* tags = [predicate getPredicateVars];
for (NSString* tag in tags) {
NSString* auxTag = [tag formKeyForPredicateType:predicateType];
if (self.rowObservers[auxTag]){
if (descriptor && [predicate isKindOfClass:[NSPredicate class]]) {
NSMutableArray *tags = [predicate getPredicateVars];
for (NSString *tag in tags) {
NSString *auxTag = [tag formKeyForPredicateType:predicateType];
if (self.rowObservers[auxTag]) {
[self.rowObservers[auxTag] removeObject:descriptor];
}
}
+41 -38
View File
@@ -43,22 +43,22 @@ typedef NS_ENUM(NSUInteger, XLFormPresentationMode) {
XLFormPresentationModePresent
};
typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLFormRowDescriptor* __nonnull rowDescriptor);
typedef void(^XLOnChangeBlock)(id __nullable oldValue, id __nullable newValue, XLFormRowDescriptor * __nonnull rowDescriptor);
@interface XLFormRowDescriptor : NSObject
@property (nullable) id cellClass;
@property (readwrite, nullable) NSString * tag;
@property (readonly, nonnull) NSString * rowType;
@property (nullable) NSString * title;
@property (nonatomic, nullable) id value;
@property (nullable) Class valueTransformer;
@property UITableViewCellStyle cellStyle;
@property (nonatomic) CGFloat height;
@property (nonatomic, nullable, strong) id cellClass;
@property (nonatomic, nullable, copy , readwrite) NSString * tag;
@property (nonatomic, nonnull , copy , readonly) NSString * rowType;
@property (nonatomic, nullable, copy ) NSString * title;
@property (nonatomic, nullable, strong) id value;
@property (nonatomic, nullable, strong) Class valueTransformer;
@property (nonatomic, assign ) UITableViewCellStyle cellStyle;
@property (nonatomic, assign ) CGFloat height;
@property (copy, nullable) XLOnChangeBlock onChangeBlock;
@property BOOL useValueFormatterDuringInput;
@property (nullable) NSFormatter *valueFormatter;
@property (nonatomic, copy , nullable) XLOnChangeBlock onChangeBlock;
@property (nonatomic, assign) BOOL useValueFormatterDuringInput;
@property (nonatomic, strong, nullable) NSFormatter *valueFormatter;
// returns the display text for the row descriptor, taking into account NSFormatters and default placeholder values
- (nonnull NSString *) displayTextValue;
@@ -66,19 +66,22 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
// 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;
@property (nonatomic, readonly, nonnull) NSMutableDictionary * cellConfigAtConfigure;
@property (nonatomic, readonly, nonnull, strong) NSMutableDictionary * cellConfig;
@property (nonatomic, readonly, nonnull, strong) NSMutableDictionary * cellConfigForSelector;
@property (nonatomic, readonly, nonnull, strong) NSMutableDictionary * cellConfigIfDisabled;
@property (nonatomic, readonly, nonnull, strong) NSMutableDictionary * cellConfigAtConfigure;
@property (nonnull) id disabled;
@property (nonatomic, nonnull, strong) id disabled;
-(BOOL)isDisabled;
@property (nonnull) id hidden;
@property (nonatomic, nonnull, strong) id hidden;
-(BOOL)isHidden;
@property (getter=isRequired) BOOL required;
@property (nonnull) XLFormAction * action;
@property (getter=isRequired, nonatomic, assign) BOOL required;
@property (weak, null_unspecified) XLFormSectionDescriptor * sectionDescriptor;
@property (nonatomic, nonnull, strong) XLFormAction * action;
@property (nonatomic, weak, null_unspecified) XLFormSectionDescriptor * sectionDescriptor;
+(nonnull instancetype)formRowDescriptorWithTag:(nullable NSString *)tag rowType:(nonnull NSString *)rowType;
+(nonnull instancetype)formRowDescriptorWithTag:(nullable NSString *)tag rowType:(nonnull NSString *)rowType title:(nullable NSString *)title;
@@ -86,7 +89,7 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
-(nonnull XLFormBaseCell *)cellForFormController:(nonnull XLFormViewController *)formController;
@property (nullable) NSString *requireMsg;
@property (nonatomic, nullable, copy) NSString *requireMsg;
-(void)addValidator:(nonnull id<XLFormValidatorProtocol>)validator;
-(void)removeValidator:(nonnull id<XLFormValidatorProtocol>)validator;
-(nullable XLFormValidationStatus *)doValidation;
@@ -94,9 +97,9 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
// ===========================
// property used for Selectors
// ===========================
@property (nullable) NSString * noValueDisplayText;
@property (nullable) NSString * selectorTitle;
@property (nullable) NSArray * selectorOptions;
@property (nonatomic, nullable, copy) NSString * noValueDisplayText;
@property (nonatomic, nullable, copy) NSString * selectorTitle;
@property (nonatomic, nullable, strong) NSArray * selectorOptions;
@property (null_unspecified) id leftRightSelectorLeftOptionSelected;
@@ -125,13 +128,13 @@ typedef NS_ENUM(NSUInteger, XLFormLeftRightSelectorOptionLeftValueChangePolicy)
@interface XLFormLeftRightSelectorOption : NSObject
@property (nonatomic, assign) XLFormLeftRightSelectorOptionLeftValueChangePolicy leftValueChangePolicy;
@property (readonly, nonnull) id leftValue;
@property (readonly, nonnull) NSArray * rightOptions;
@property (readonly, null_unspecified) NSString * httpParameterKey;
@property (nullable) Class rightSelectorControllerClass;
@property (nonatomic, readonly, nonnull) id leftValue;
@property (nonatomic, readonly, nonnull) NSArray * rightOptions;
@property (nonatomic, readonly, null_unspecified, copy) NSString * httpParameterKey;
@property (nonatomic, nullable) Class rightSelectorControllerClass;
@property (nullable) NSString * noValueDisplayText;
@property (nullable) NSString * selectorTitle;
@property (nonatomic, nullable, copy) NSString * noValueDisplayText;
@property (nonatomic, nullable, copy) NSString * selectorTitle;
+(nonnull XLFormLeftRightSelectorOption *)formLeftRightSelectorOptionWithLeftValue:(nonnull id)leftValue
@@ -153,16 +156,16 @@ typedef NS_ENUM(NSUInteger, XLFormLeftRightSelectorOptionLeftValueChangePolicy)
@interface XLFormAction : NSObject
@property (nullable, nonatomic, strong) Class viewControllerClass;
@property (nullable, nonatomic, strong) NSString * viewControllerStoryboardId;
@property (nullable, nonatomic, strong) NSString * viewControllerNibName;
@property (nullable, nonatomic) Class viewControllerClass;
@property (nullable, nonatomic, copy) NSString * viewControllerStoryboardId;
@property (nullable, nonatomic, copy) NSString * viewControllerNibName;
@property (nonatomic) XLFormPresentationMode viewControllerPresentationMode;
@property (nonatomic, assign) XLFormPresentationMode viewControllerPresentationMode;
@property (nullable, nonatomic, strong) void (^formBlock)(XLFormRowDescriptor * __nonnull sender);
@property (nullable, nonatomic, copy) void (^formBlock)(XLFormRowDescriptor * __nonnull sender);
@property (nullable, nonatomic) SEL formSelector;
@property (nullable, nonatomic, strong) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead");
@property (nullable, nonatomic, strong) NSString * formSegueIdentifier;
@property (nullable, nonatomic, strong) Class formSegueClass;
@property (nullable, nonatomic, copy) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead");
@property (nullable, nonatomic, copy) NSString * formSegueIdentifier;
@property (nullable, nonatomic) Class formSegueClass;
@end
+182 -120
View File
@@ -28,12 +28,12 @@
#import "XLFormRowDescriptor.h"
#import "NSString+XLFormAdditions.h"
CGFloat XLFormUnspecifiedCellHeight = -1.0;
CGFloat XLFormUnspecifiedCellHeight = -3.0;
CGFloat XLFormRowInitialHeight = -2;
@interface XLFormDescriptor (_XLFormRowDescriptor)
@property (readonly) NSDictionary* allRowsByTag;
@property (nonatomic, readonly, strong) NSDictionary *allRowsByTag;
-(void)addObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
-(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
@@ -42,22 +42,26 @@ CGFloat XLFormRowInitialHeight = -2;
@interface XLFormSectionDescriptor (_XLFormRowDescriptor)
-(void)showFormRow:(XLFormRowDescriptor*)formRow;
-(void)hideFormRow:(XLFormRowDescriptor*)formRow;
-(void)showFormRow:(XLFormRowDescriptor *)formRow;
-(void)hideFormRow:(XLFormRowDescriptor *)formRow;
@end
#import "NSObject+XLFormAdditions.h"
NSString * const XLValueKey = @"value";
NSString * const XLDisablePredicateCacheKey = @"disablePredicateCache";
NSString * const XLHidePredicateCacheKey = @"hidePredicateCache";
@interface XLFormRowDescriptor() <NSCopying>
@property XLFormBaseCell * cell;
@property (nonatomic) NSMutableArray *validators;
@property (nonatomic, strong) XLFormBaseCell *cell;
@property (nonatomic, strong) NSMutableArray *validators;
@property BOOL isDirtyDisablePredicateCache;
@property (nonatomic) NSNumber* disablePredicateCache;
@property BOOL isDirtyHidePredicateCache;
@property (nonatomic) NSNumber* hidePredicateCache;
@property (nonatomic, assign) BOOL isDirtyDisablePredicateCache;
@property (nonatomic, copy ) NSNumber *disablePredicateCache;
@property (nonatomic, assign) BOOL isDirtyHidePredicateCache;
@property (nonatomic, copy ) NSNumber *hidePredicateCache;
@end
@@ -69,6 +73,7 @@ CGFloat XLFormRowInitialHeight = -2;
@synthesize hidePredicateCache = _hidePredicateCache;
@synthesize disablePredicateCache = _disablePredicateCache;
@synthesize cellConfig = _cellConfig;
@synthesize cellConfigForSelector = _cellConfigForSelector;
@synthesize cellConfigIfDisabled = _cellConfigIfDisabled;
@synthesize cellConfigAtConfigure = _cellConfigAtConfigure;
@synthesize height = _height;
@@ -80,8 +85,7 @@ CGFloat XLFormRowInitialHeight = -2;
-(instancetype)initWithTag:(NSString *)tag rowType:(NSString *)rowType title:(NSString *)title;
{
self = [super init];
if (self){
if (self = [super init]) {
NSAssert(((![rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover] && ![rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) || (([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) && ([rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover] || [rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]))), @"You must be running under UIUserInterfaceIdiomPad to use either XLFormRowDescriptorTypeSelectorPopover or XLFormRowDescriptorTypeMultipleSelectorPopover rows.");
_tag = tag;
_disabled = @NO;
@@ -98,11 +102,19 @@ CGFloat XLFormRowInitialHeight = -2;
_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];
[self addObserver:self
forKeyPath:XLValueKey
options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
[self addObserver:self
forKeyPath:XLDisablePredicateCacheKey
options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
[self addObserver:self
forKeyPath:XLHidePredicateCacheKey
options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:0];
}
return self;
}
@@ -118,13 +130,16 @@ CGFloat XLFormRowInitialHeight = -2;
-(XLFormBaseCell *)cellForFormController:(XLFormViewController * __unused)formController
{
if (!_cell){
if (!_cell) {
id cellClass = self.cellClass ?: [XLFormViewController cellClassesForRowDescriptorTypes][self.rowType];
NSBundle *bundle = [NSBundle mainBundle];
NSString *cellClassString = cellClass;
NSString *cellResource = nil;
NSAssert(cellClass, @"Not defined XLFormRowDescriptorType: %@", self.rowType ?: @"");
if ([cellClass isKindOfClass:[NSString class]]) {
NSString *cellClassString = cellClass;
NSString *cellResource = nil;
NSBundle *bundle = nil;
if ([cellClassString rangeOfString:@"/"].location != NSNotFound) {
NSArray *components = [cellClassString componentsSeparatedByString:@"/"];
cellResource = [components lastObject];
@@ -132,86 +147,109 @@ CGFloat XLFormRowInitialHeight = -2;
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:folderName];
bundle = [NSBundle bundleWithPath:bundlePath];
} else {
bundle = [NSBundle bundleForClass:NSClassFromString(cellClass)];
cellResource = cellClassString;
}
NSParameterAssert(bundle != nil);
NSParameterAssert(cellResource != nil);
if ([bundle pathForResource:cellResource ofType:@"nib"]){
_cell = [[bundle loadNibNamed:cellResource owner:nil options:nil] firstObject];
cellResource = [cellClassString componentsSeparatedByString:@"."].lastObject;
}
} else {
cellResource = [NSStringFromClass(cellClass) componentsSeparatedByString:@"."].lastObject;
}
if ([bundle pathForResource:cellResource ofType:@"nib"]) {
_cell = [[bundle loadNibNamed:cellResource owner:nil options:nil] firstObject];
} else {
_cell = [[cellClass alloc] initWithStyle:self.cellStyle reuseIdentifier:nil];
}
_cell.rowDescriptor = self;
NSAssert([_cell isKindOfClass:[XLFormBaseCell class]], @"UITableViewCell must extend from XLFormBaseCell");
[self configureCellAtCreationTime];
}
return _cell;
}
- (void)configureCellAtCreationTime
{
[self.cellConfigAtConfigure enumerateKeysAndObjectsUsingBlock:^(NSString *keyPath, id value, __unused BOOL *stop) {
[_cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
[self.cell setValue:(value == [NSNull null]) ? nil : value forKeyPath:keyPath];
}];
}
-(NSMutableDictionary *)cellConfig
{
if (_cellConfig) return _cellConfig;
_cellConfig = [NSMutableDictionary dictionary];
if (!_cellConfig) {
_cellConfig = [NSMutableDictionary dictionary];
}
return _cellConfig;
}
-(NSMutableDictionary *)cellConfigForSelector
{
if (!_cellConfigForSelector) {
_cellConfigForSelector = [NSMutableDictionary dictionary];
}
return _cellConfigForSelector;
}
-(NSMutableDictionary *)cellConfigIfDisabled
{
if (_cellConfigIfDisabled) return _cellConfigIfDisabled;
_cellConfigIfDisabled = [NSMutableDictionary dictionary];
if (!_cellConfigIfDisabled) {
_cellConfigIfDisabled = [NSMutableDictionary dictionary];
}
return _cellConfigIfDisabled;
}
-(NSMutableDictionary *)cellConfigAtConfigure
{
if (_cellConfigAtConfigure) return _cellConfigAtConfigure;
_cellConfigAtConfigure = [NSMutableDictionary dictionary];
if (!_cellConfigAtConfigure) {
_cellConfigAtConfigure = [NSMutableDictionary dictionary];
}
return _cellConfigAtConfigure;
}
-(NSString*)editTextValue
-(NSString *)editTextValue
{
NSString *result = @"";
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];
result = [self displayTextValue];
}
else {
// have formatter, but we don't want to use it during editing
result = [self.value displayText];
}
}else{
// have value, but no formatter, use the value's displayText
return [self.value displayText];
}
}else{
// placeholder
return @"";
else {
// have value, but no formatter, use the value's displayText
result = [self.value displayText];
}
}
return result;
}
-(NSString*)displayTextValue
-(NSString *)displayTextValue
{
NSString *result = self.noValueDisplayText;
if (self.value) {
if (self.valueFormatter) {
return [self.valueFormatter stringForObjectValue:self.value];
result = [self.valueFormatter stringForObjectValue:self.value];
}
else{
return [self.value displayText];
else {
result = [self.value displayText];
}
}
else {
return self.noValueDisplayText;
}
return result;
}
-(NSString *)description
@@ -221,9 +259,10 @@ CGFloat XLFormRowInitialHeight = -2;
-(XLFormAction *)action
{
if (!_action){
if (!_action) {
_action = [[XLFormAction alloc] init];
}
return _action;
}
@@ -234,13 +273,15 @@ CGFloat XLFormRowInitialHeight = -2;
-(CGFloat)height
{
if (_height == XLFormRowInitialHeight){
if (_height == XLFormRowInitialHeight) {
if ([[self.cell class] respondsToSelector:@selector(formDescriptorCellHeightForRowDescriptor:)]){
return [[self.cell class] formDescriptorCellHeightForRowDescriptor:self];
} else {
}
else {
_height = XLFormUnspecifiedCellHeight;
}
}
return _height;
}
@@ -251,71 +292,76 @@ CGFloat XLFormRowInitialHeight = -2;
// In the implementation
-(id)copyWithZone:(NSZone *)zone
{
XLFormRowDescriptor * rowDescriptorCopy = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:[self.rowType copy] title:[self.title copy]];
XLFormRowDescriptor *rowDescriptorCopy = [XLFormRowDescriptor formRowDescriptorWithTag:nil
rowType:[self.rowType copy]
title:[self.title copy]];
rowDescriptorCopy.cellClass = [self.cellClass copy];
[rowDescriptorCopy.cellConfig addEntriesFromDictionary:self.cellConfig];
[rowDescriptorCopy.cellConfigAtConfigure addEntriesFromDictionary:self.cellConfigAtConfigure];
rowDescriptorCopy.valueTransformer = [self.valueTransformer copy];
rowDescriptorCopy->_hidden = _hidden;
rowDescriptorCopy->_disabled = _disabled;
rowDescriptorCopy.hidden = self.hidden;
rowDescriptorCopy.disabled = self.disabled;
rowDescriptorCopy.required = self.isRequired;
rowDescriptorCopy.isDirtyDisablePredicateCache = YES;
rowDescriptorCopy.isDirtyHidePredicateCache = YES;
rowDescriptorCopy.validators = [self.validators mutableCopy];
// =====================
// properties for Button
// =====================
rowDescriptorCopy.action = [self.action copy];
// ===========================
// property used for Selectors
// ===========================
rowDescriptorCopy.noValueDisplayText = [self.noValueDisplayText copy];
rowDescriptorCopy.selectorTitle = [self.selectorTitle copy];
rowDescriptorCopy.selectorOptions = [self.selectorOptions copy];
rowDescriptorCopy.leftRightSelectorLeftOptionSelected = [self.leftRightSelectorLeftOptionSelected copy];
return rowDescriptorCopy;
}
-(void)dealloc
{
[self removeObserver:self forKeyPath:XLValueKey];
[self removeObserver:self forKeyPath:XLDisablePredicateCacheKey];
[self removeObserver:self forKeyPath:XLHidePredicateCacheKey];
[self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeDisabled];
[self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeHidden];
@try {
[self removeObserver:self forKeyPath:@"value"];
}
@catch (NSException * __unused exception) {}
@try {
[self removeObserver:self forKeyPath:@"disablePredicateCache"];
}
@catch (NSException * __unused exception) {}
@try {
[self removeObserver:self forKeyPath:@"hidePredicateCache"];
}
@catch (NSException * __unused exception) {}
_cell = nil;
[self.validators removeAllObjects];
self.validators = nil;
}
#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (!self.sectionDescriptor) return;
if (object == self && ([keyPath isEqualToString:@"value"] || [keyPath isEqualToString:@"hidePredicateCache"] || [keyPath isEqualToString:@"disablePredicateCache"])){
if (!self.sectionDescriptor) {
return;
}
else if (object == self && ([keyPath isEqualToString:XLValueKey] ||
[keyPath isEqualToString:XLHidePredicateCacheKey] || [keyPath isEqualToString:XLDisablePredicateCacheKey])) {
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeSetting)]){
id newValue = [change objectForKey:NSKeyValueChangeNewKey];
id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
if ([keyPath isEqualToString:@"value"]){
if ([keyPath isEqualToString:XLValueKey]) {
[self.sectionDescriptor.formDescriptor.delegate formRowDescriptorValueHasChanged:object oldValue:oldValue newValue:newValue];
if (self.onChangeBlock) {
self.onChangeBlock(oldValue, newValue, self);
}
}
else{
[self.sectionDescriptor.formDescriptor.delegate formRowDescriptorPredicateHasChanged:object oldValue:oldValue newValue:newValue predicateType:([keyPath isEqualToString:@"hidePredicateCache"] ? XLPredicateTypeHidden : XLPredicateTypeDisabled)];
else {
[self.sectionDescriptor.formDescriptor.delegate formRowDescriptorPredicateHasChanged:object
oldValue:oldValue
newValue:newValue
predicateType:([keyPath isEqualToString:XLHidePredicateCacheKey] ? XLPredicateTypeHidden : XLPredicateTypeDisabled)];
}
}
}
@@ -325,12 +371,14 @@ CGFloat XLFormRowInitialHeight = -2;
-(BOOL)isDisabled
{
if (self.sectionDescriptor.formDescriptor.isDisabled){
if (self.sectionDescriptor.formDescriptor.isDisabled) {
return YES;
}
if (self.isDirtyDisablePredicateCache) {
[self evaluateIsDisabled];
}
return [self.disablePredicateCache boolValue];
}
@@ -339,11 +387,12 @@ CGFloat XLFormRowInitialHeight = -2;
if ([_disabled isKindOfClass:[NSPredicate class]]){
[self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeDisabled];
}
_disabled = [disabled isKindOfClass:[NSString class]] ? [disabled formPredicate] : disabled;
if ([_disabled isKindOfClass:[NSPredicate class]]){
[self.sectionDescriptor.formDescriptor addObserversOfObject:self predicateType:XLPredicateTypeDisabled];
}
[self evaluateIsDisabled];
}
@@ -352,7 +401,8 @@ CGFloat XLFormRowInitialHeight = -2;
if ([_disabled isKindOfClass:[NSPredicate class]]) {
if (!self.sectionDescriptor.formDescriptor) {
self.isDirtyDisablePredicateCache = YES;
} else {
}
else {
@try {
self.disablePredicateCache = @([_disabled evaluateWithObject:self substitutionVariables:self.sectionDescriptor.formDescriptor.allRowsByTag ?: @{}]);
}
@@ -362,12 +412,14 @@ CGFloat XLFormRowInitialHeight = -2;
};
}
}
else{
else {
self.disablePredicateCache = _disabled;
}
if ([self.disablePredicateCache boolValue]){
if ([self.disablePredicateCache boolValue]) {
[self.cell resignFirstResponder];
}
return [self.disablePredicateCache boolValue];
}
@@ -378,9 +430,9 @@ CGFloat XLFormRowInitialHeight = -2;
-(void)setDisablePredicateCache:(NSNumber*)disablePredicateCache
{
NSParameterAssert(disablePredicateCache);
NSParameterAssert(disablePredicateCache != nil);
self.isDirtyDisablePredicateCache = NO;
if (!_disablePredicateCache || ![_disablePredicateCache isEqualToNumber:disablePredicateCache]){
if (_disablePredicateCache == nil || ![_disablePredicateCache isEqualToNumber:disablePredicateCache]){
_disablePredicateCache = disablePredicateCache;
}
}
@@ -399,9 +451,9 @@ CGFloat XLFormRowInitialHeight = -2;
-(void)setHidePredicateCache:(NSNumber *)hidePredicateCache
{
NSParameterAssert(hidePredicateCache);
NSParameterAssert(hidePredicateCache != nil);
self.isDirtyHidePredicateCache = NO;
if (!_hidePredicateCache || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]){
if (_hidePredicateCache == nil || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]){
_hidePredicateCache = hidePredicateCache;
}
}
@@ -411,6 +463,7 @@ CGFloat XLFormRowInitialHeight = -2;
if (self.isDirtyHidePredicateCache) {
return [self evaluateIsHidden];
}
return [self.hidePredicateCache boolValue];
}
@@ -419,7 +472,8 @@ CGFloat XLFormRowInitialHeight = -2;
if ([_hidden isKindOfClass:[NSPredicate class]]) {
if (!self.sectionDescriptor.formDescriptor) {
self.isDirtyHidePredicateCache = YES;
} else {
}
else {
@try {
self.hidePredicateCache = @([_hidden evaluateWithObject:self substitutionVariables:self.sectionDescriptor.formDescriptor.allRowsByTag ?: @{}]);
}
@@ -429,16 +483,18 @@ CGFloat XLFormRowInitialHeight = -2;
};
}
}
else{
else {
self.hidePredicateCache = _hidden;
}
if ([self.hidePredicateCache boolValue]){
[self.cell resignFirstResponder];
[self.sectionDescriptor hideFormRow:self];
}
else{
else {
[self.sectionDescriptor showFormRow:self];
}
return [self.hidePredicateCache boolValue];
}
@@ -448,10 +504,12 @@ CGFloat XLFormRowInitialHeight = -2;
if ([_hidden isKindOfClass:[NSPredicate class]]){
[self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeHidden];
}
_hidden = [hidden isKindOfClass:[NSString class]] ? [hidden formPredicate] : hidden;
if ([_hidden isKindOfClass:[NSPredicate class]]){
[self.sectionDescriptor.formDescriptor addObserversOfObject:self predicateType:XLPredicateTypeHidden];
}
[self evaluateIsHidden]; // check and update if this row should be hidden.
}
@@ -465,34 +523,35 @@ CGFloat XLFormRowInitialHeight = -2;
-(void)addValidator:(id<XLFormValidatorProtocol>)validator
{
if (validator == nil || ![validator conformsToProtocol:@protocol(XLFormValidatorProtocol)])
if (validator == nil || ![validator conformsToProtocol:@protocol(XLFormValidatorProtocol)]) {
return;
if(![self.validators containsObject:validator]) {
}
else if (![self.validators containsObject:validator]) {
[self.validators addObject:validator];
}
}
-(void)removeValidator:(id<XLFormValidatorProtocol>)validator
{
if (validator == nil|| ![validator conformsToProtocol:@protocol(XLFormValidatorProtocol)])
if (validator == nil || ![validator conformsToProtocol:@protocol(XLFormValidatorProtocol)]) {
return;
if ([self.validators containsObject:validator]) {
}
else if ([self.validators containsObject:validator]) {
[self.validators removeObject:validator];
}
}
- (BOOL)valueIsEmpty
{
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);
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
{
XLFormValidationStatus *valStatus = nil;
if (self.required) {
// do required validation here
if ([self valueIsEmpty]) {
@@ -500,22 +559,24 @@ CGFloat XLFormRowInitialHeight = -2;
NSString *msg = nil;
if (self.requireMsg != nil) {
msg = self.requireMsg;
} else {
}
else {
// default message for required msg
msg = NSLocalizedString(@"%@ can't be empty", nil);
}
if (self.title != nil) {
if (self.title.length) {
valStatus.msg = [NSString stringWithFormat:msg, self.title];
} else {
}
else {
valStatus.msg = [NSString stringWithFormat:msg, self.tag];
}
return valStatus;
}
}
// custom validator
for(id<XLFormValidatorProtocol> v in self.validators) {
for (id<XLFormValidatorProtocol> v in self.validators) {
if ([v conformsToProtocol:@protocol(XLFormValidatorProtocol)]) {
XLFormValidationStatus *vStatus = [v isValid:self];
// fail validation
@@ -523,10 +584,12 @@ CGFloat XLFormRowInitialHeight = -2;
return vStatus;
}
valStatus = vStatus;
} else {
}
else {
valStatus = nil;
}
}
return valStatus;
}
@@ -580,15 +643,15 @@ CGFloat XLFormRowInitialHeight = -2;
}
-(id)initWithLeftValue:(NSString *)leftValue httpParameterKey:(NSString *)httpParameterKey rightOptions:(NSArray *)rightOptions
-(instancetype)initWithLeftValue:(NSString *)leftValue httpParameterKey:(NSString *)httpParameterKey rightOptions:(NSArray *)rightOptions
{
self = [super init];
if (self){
if (self = [super init]) {
_selectorTitle = nil;
_leftValue = leftValue;
_rightOptions = rightOptions;
_httpParameterKey = httpParameterKey;
}
return self;
}
@@ -599,10 +662,10 @@ CGFloat XLFormRowInitialHeight = -2;
- (instancetype)init
{
self = [super init];
if (self) {
if (self = [super init]) {
_viewControllerPresentationMode = XLFormPresentationModeDefault;
}
return self;
}
@@ -614,24 +677,25 @@ CGFloat XLFormRowInitialHeight = -2;
if (self.viewControllerClass){
actionCopy.viewControllerClass = [self.viewControllerClass copy];
}
else if ([self.viewControllerStoryboardId length] != 0){
else if ([self.viewControllerStoryboardId length] != 0) {
actionCopy.viewControllerStoryboardId = [self.viewControllerStoryboardId copy];
}
else if ([self.viewControllerNibName length] != 0){
else if ([self.viewControllerNibName length] != 0) {
actionCopy.viewControllerNibName = [self.viewControllerNibName copy];
}
if (self.formBlock){
if (self.formBlock) {
actionCopy.formBlock = [self.formBlock copy];
}
else if (self.formSelector){
else if (self.formSelector) {
actionCopy.formSelector = self.formSelector;
}
else if (self.formSegueIdentifier){
else if (self.formSegueIdentifier) {
actionCopy.formSegueIdentifier = [self.formSegueIdentifier copy];
}
else if (self.formSegueClass){
actionCopy.formSegueClass = [self.formSegueClass copy];
}
return actionCopy;
}
@@ -656,7 +720,6 @@ CGFloat XLFormRowInitialHeight = -2;
_viewControllerStoryboardId = viewControllerStoryboardId;
}
-(void)setFormSelector:(SEL)formSelector
{
_formBlock = nil;
@@ -665,7 +728,6 @@ CGFloat XLFormRowInitialHeight = -2;
_formSelector = formSelector;
}
-(void)setFormBlock:(void (^)(XLFormRowDescriptor *))formBlock
{
_formSegueClass = nil;
+11 -10
View File
@@ -42,19 +42,19 @@ typedef NS_ENUM(NSUInteger, XLFormSectionInsertMode) {
@interface XLFormSectionDescriptor : NSObject
@property (nonatomic, nullable) NSString * title;
@property (nonatomic, nullable) NSString * footerTitle;
@property (readonly, nonnull) NSMutableArray * formRows;
@property (nonatomic, nullable, copy) NSString * title;
@property (nonatomic, nullable, copy) NSString * footerTitle;
@property (nonatomic, readonly, nonnull, strong) NSMutableArray * formRows;
@property (readonly) XLFormSectionInsertMode sectionInsertMode;
@property (readonly) XLFormSectionOptions sectionOptions;
@property (nullable) XLFormRowDescriptor * multivaluedRowTemplate;
@property (readonly, nullable) XLFormRowDescriptor * multivaluedAddButton;
@property (nonatomic, nullable) NSString * multivaluedTag;
@property (nonatomic, readonly, assign) XLFormSectionInsertMode sectionInsertMode;
@property (nonatomic, readonly, assign) XLFormSectionOptions sectionOptions;
@property (nonatomic, nullable, strong) XLFormRowDescriptor * multivaluedRowTemplate;
@property (nonatomic, readonly, nullable, strong) XLFormRowDescriptor * multivaluedAddButton;
@property (nonatomic, nullable, copy) NSString * multivaluedTag;
@property (weak, null_unspecified) XLFormDescriptor * formDescriptor;
@property (nonatomic, weak, null_unspecified) XLFormDescriptor * formDescriptor;
@property (nonnull) id hidden;
@property (nonatomic, nonnull, strong) id hidden;
-(BOOL)isHidden;
+(nonnull instancetype)formSection;
@@ -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
+93 -61
View File
@@ -29,15 +29,16 @@
#import "NSString+XLFormAdditions.h"
#import "UIView+XLFormAdditions.h"
NSString * const XLFormRowsKey = @"formRows";
@interface XLFormDescriptor (_XLFormSectionDescriptor)
@property (readonly) NSDictionary* allRowsByTag;
@property (nonatomic, weak, readonly) NSDictionary *allRowsByTag;
-(void)addRowToTagCollection:(XLFormRowDescriptor*)rowDescriptor;
-(void)removeRowFromTagCollection:(XLFormRowDescriptor*) rowDescriptor;
-(void)showFormSection:(XLFormSectionDescriptor*)formSection;
-(void)hideFormSection:(XLFormSectionDescriptor*)formSection;
-(void)addRowToTagCollection:(XLFormRowDescriptor *)rowDescriptor;
-(void)removeRowFromTagCollection:(XLFormRowDescriptor *) rowDescriptor;
-(void)showFormSection:(XLFormSectionDescriptor *)formSection;
-(void)hideFormSection:(XLFormSectionDescriptor *)formSection;
-(void)addObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
-(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
@@ -46,10 +47,11 @@
@interface XLFormSectionDescriptor()
@property NSMutableArray * formRows;
@property NSMutableArray * allRows;
@property BOOL isDirtyHidePredicateCache;
@property (nonatomic) NSNumber* hidePredicateCache;
@property (nonatomic, strong) NSMutableArray *formRows;
@property (nonatomic, strong) NSMutableArray *allRows;
@property (nonatomic, assign) BOOL isDirtyHidePredicateCache;
@property (nonatomic, copy ) NSNumber *hidePredicateCache;
@end
@@ -60,8 +62,7 @@
-(instancetype)init
{
self = [super init];
if (self){
if (self = [super init]) {
_formRows = [NSMutableArray array];
_allRows = [NSMutableArray array];
_sectionInsertMode = XLFormSectionInsertModeLastRow;
@@ -71,25 +72,35 @@
_hidden = @NO;
_hidePredicateCache = @NO;
_isDirtyHidePredicateCache = YES;
[self addObserver:self forKeyPath:@"formRows" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:0];
[self addObserver:self
forKeyPath:XLFormRowsKey
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:0];
}
return self;
}
-(instancetype)initWithTitle:(NSString *)title sectionOptions:(XLFormSectionOptions)sectionOptions sectionInsertMode:(XLFormSectionInsertMode)sectionInsertMode{
self = [self init];
if (self){
-(instancetype)initWithTitle:(NSString *)title sectionOptions:(XLFormSectionOptions)sectionOptions sectionInsertMode:(XLFormSectionInsertMode)sectionInsertMode
{
if (self = [self init]) {
_sectionInsertMode = sectionInsertMode;
_sectionOptions = sectionOptions;
_title = title;
if ([self canInsertUsingButton]){
_multivaluedAddButton = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:XLFormRowDescriptorTypeButton title:@"Add Item"];
if ([self canInsertUsingButton]) {
_multivaluedAddButton = [XLFormRowDescriptor formRowDescriptorWithTag:nil
rowType:XLFormRowDescriptorTypeButton
title:@"Add Item"];
[_multivaluedAddButton.cellConfig setObject:@(NSTextAlignmentNatural) forKey:@"textLabel.textAlignment"];
_multivaluedAddButton.action.formSelector = NSSelectorFromString(@"multivaluedInsertButtonTapped:");
[self insertObject:_multivaluedAddButton inFormRowsAtIndex:0];
[self insertObject:_multivaluedAddButton inAllRowsAtIndex:0];
}
}
return self;
}
@@ -125,7 +136,13 @@
-(void)addFormRow:(XLFormRowDescriptor *)formRow
{
[self insertObject:formRow inAllRowsAtIndex:([self canInsertUsingButton] ? MAX(0, [self.formRows count] - 1) : [self.allRows count])];
NSUInteger index = [self.allRows count];
if ([self canInsertUsingButton]) {
index = ([self.formRows count] > 0) ? [self.formRows count] - 1 : 0;
}
[self insertObject:formRow inAllRowsAtIndex:index];
}
-(void)addFormRow:(XLFormRowDescriptor *)formRow afterRow:(XLFormRowDescriptor *)afterRow
@@ -136,26 +153,23 @@
}
else { //case when afterRow does not exist. Just insert at the end.
[self addFormRow:formRow];
return;
}
}
-(void)addFormRow:(XLFormRowDescriptor *)formRow beforeRow:(XLFormRowDescriptor *)beforeRow
{
NSUInteger allRowIndex = [self.allRows indexOfObject:beforeRow];
if (allRowIndex != NSNotFound) {
[self insertObject:formRow inAllRowsAtIndex:allRowIndex];
}
else { //case when afterRow does not exist. Just insert at the end.
[self addFormRow:formRow];
return;
}
}
-(void)removeFormRowAtIndex:(NSUInteger)index
{
if (self.formRows.count > index){
if (self.formRows.count > index) {
XLFormRowDescriptor *formRow = [self.formRows objectAtIndex:index];
NSUInteger allRowIndex = [self.allRows indexOfObject:formRow];
[self removeObjectFromFormRowsAtIndex:index];
@@ -166,21 +180,21 @@
-(void)removeFormRow:(XLFormRowDescriptor *)formRow
{
NSUInteger index = NSNotFound;
if ((index = [self.formRows indexOfObject:formRow]) != NSNotFound){
if ((index = [self.formRows indexOfObject:formRow]) != NSNotFound) {
[self removeFormRowAtIndex:index];
}
else if ((index = [self.allRows indexOfObject:formRow]) != NSNotFound){
if (self.allRows.count > index){
else if ((index = [self.allRows indexOfObject:formRow]) != NSNotFound) {
if (self.allRows.count > index) {
[self removeObjectFromAllRowsAtIndex:index];
}
};
}
}
- (void)moveRowAtIndexPath:(NSIndexPath *)sourceIndex toIndexPath:(NSIndexPath *)destinationIndex
{
if ((sourceIndex.row < self.formRows.count) && (destinationIndex.row < self.formRows.count) && (sourceIndex.row != destinationIndex.row)){
XLFormRowDescriptor * row = [self objectInFormRowsAtIndex:sourceIndex.row];
XLFormRowDescriptor * destRow = [self objectInFormRowsAtIndex:destinationIndex.row];
if ((sourceIndex.row < self.formRows.count) && (destinationIndex.row < self.formRows.count) && (sourceIndex.row != destinationIndex.row)) {
XLFormRowDescriptor *row = [self objectInFormRowsAtIndex:sourceIndex.row];
XLFormRowDescriptor *destRow = [self objectInFormRowsAtIndex:destinationIndex.row];
[self.formRows removeObjectAtIndex:sourceIndex.row];
[self.formRows insertObject:row atIndex:destinationIndex.row];
@@ -191,11 +205,15 @@
-(void)dealloc
{
[self removeObserver:self forKeyPath:XLFormRowsKey];
[self.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeHidden];
@try {
[self removeObserver:self forKeyPath:@"formRows"];
}
@catch (NSException * __unused exception) {}
[self.formRows removeAllObjects];
self.formRows = nil;
[self.allRows removeAllObjects];
self.allRows = nil;
}
#pragma mark - Show/hide rows
@@ -206,13 +224,15 @@
if (formIndex != NSNotFound) {
return;
}
NSUInteger index = [self.allRows indexOfObject:formRow];
if (index != NSNotFound){
if (index != NSNotFound) {
while (formIndex == NSNotFound && index > 0) {
XLFormRowDescriptor* previous = [self.allRows objectAtIndex:--index];
formIndex = [self.formRows indexOfObject:previous];
}
if (formIndex == NSNotFound){ // index == 0 => insert at the beginning
if (formIndex == NSNotFound) { // index == 0 => insert at the beginning
[self insertObject:formRow inFormRowsAtIndex:0];
}
else {
@@ -224,36 +244,41 @@
-(void)hideFormRow:(XLFormRowDescriptor*)formRow{
NSUInteger index = [self.formRows indexOfObject:formRow];
if (index != NSNotFound){
if (index != NSNotFound) {
[self removeObjectFromFormRowsAtIndex:index];
}
}
#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- (void)observeValueForKeyPath:(nullable NSString *)keyPath
ofObject:(nullable id)object
change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change
context:(nullable void *)context
{
if (!self.formDescriptor.delegate) return;
if ([keyPath isEqualToString:@"formRows"]){
if ([self.formDescriptor.formSections containsObject:self]){
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeInsertion)]){
NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormRowDescriptor * formRow = [((XLFormSectionDescriptor *)object).formRows objectAtIndex:indexSet.firstIndex];
if (!self.formDescriptor.delegate) {
return;
}
else if ([keyPath isEqualToString:XLFormRowsKey]) {
if ([self.formDescriptor.formSections containsObject:self]) {
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeInsertion)]) {
NSIndexSet *indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormRowDescriptor *formRow = [((XLFormSectionDescriptor *)object).formRows objectAtIndex:indexSet.firstIndex];
NSUInteger sectionIndex = [self.formDescriptor.formSections indexOfObject:object];
[self.formDescriptor.delegate formRowHasBeenAdded:formRow atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
[self.formDescriptor.delegate formRowHasBeenAdded:formRow
atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
}
else if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeRemoval)]){
NSIndexSet * indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormRowDescriptor * removedRow = [[change objectForKey:NSKeyValueChangeOldKey] objectAtIndex:0];
else if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeRemoval)]) {
NSIndexSet *indexSet = [change objectForKey:NSKeyValueChangeIndexesKey];
XLFormRowDescriptor *removedRow = [[change objectForKey:NSKeyValueChangeOldKey] objectAtIndex:0];
NSUInteger sectionIndex = [self.formDescriptor.formSections indexOfObject:object];
[self.formDescriptor.delegate formRowHasBeenRemoved:removedRow atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
[self.formDescriptor.delegate formRowHasBeenRemoved:removedRow
atIndexPath:[NSIndexPath indexPathForRow:indexSet.firstIndex inSection:sectionIndex]];
}
}
}
}
#pragma mark - KVC
-(NSUInteger)countOfFormRows
@@ -334,9 +359,9 @@
-(void)setHidePredicateCache:(NSNumber *)hidePredicateCache
{
NSParameterAssert(hidePredicateCache);
NSParameterAssert(hidePredicateCache != nil);
self.isDirtyHidePredicateCache = NO;
if (!_hidePredicateCache || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]){
if (_hidePredicateCache == nil || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]) {
_hidePredicateCache = hidePredicateCache;
}
}
@@ -346,6 +371,7 @@
if (self.isDirtyHidePredicateCache) {
return [self evaluateIsHidden];
}
return [self.hidePredicateCache boolValue];
}
@@ -354,7 +380,8 @@
if ([_hidden isKindOfClass:[NSPredicate class]]) {
if (!self.formDescriptor) {
self.isDirtyHidePredicateCache = YES;
} else {
}
else {
@try {
self.hidePredicateCache = @([_hidden evaluateWithObject:self substitutionVariables:self.formDescriptor.allRowsByTag ?: @{}]);
}
@@ -364,21 +391,24 @@
};
}
}
else{
else {
self.hidePredicateCache = _hidden;
}
if ([self.hidePredicateCache boolValue]){
if ([self.formDescriptor.delegate isKindOfClass:[XLFormViewController class]]){
XLFormBaseCell* firtResponder = (XLFormBaseCell*) [((XLFormViewController*)self.formDescriptor.delegate).tableView findFirstResponder];
if ([firtResponder isKindOfClass:[XLFormBaseCell class]] && firtResponder.rowDescriptor.sectionDescriptor == self){
if ([self.hidePredicateCache boolValue]) {
if ([self.formDescriptor.delegate isKindOfClass:[XLFormViewController class]]) {
XLFormBaseCell *firtResponder = (XLFormBaseCell *)[((XLFormViewController *)self.formDescriptor.delegate).tableView findFirstResponder];
if ([firtResponder isKindOfClass:[XLFormBaseCell class]] && firtResponder.rowDescriptor.sectionDescriptor == self) {
[firtResponder resignFirstResponder];
}
}
[self.formDescriptor hideFormSection:self];
}
else{
else {
[self.formDescriptor showFormSection:self];
}
return [self.hidePredicateCache boolValue];
}
@@ -390,13 +420,15 @@
-(void)setHidden:(id)hidden
{
if ([_hidden isKindOfClass:[NSPredicate class]]){
if ([_hidden isKindOfClass:[NSPredicate class]]) {
[self.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeHidden];
}
_hidden = [hidden isKindOfClass:[NSString class]] ? [hidden formPredicate] : hidden;
if ([_hidden isKindOfClass:[NSPredicate class]]){
if ([_hidden isKindOfClass:[NSPredicate class]]) {
[self.formDescriptor addObserversOfObject:self predicateType:XLPredicateTypeHidden];
}
[self evaluateIsHidden]; // check and update if this row should be hidden.
}
+1 -1
View File
@@ -28,7 +28,7 @@
@interface UIView (XLFormAdditions)
+(id)autolayoutView;
+(instancetype)autolayoutView;
-(NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view;
-(UIView *)findFirstResponder;
-(UITableViewCell<XLFormDescriptorCell> *)formDescriptorCell;
+34 -19
View File
@@ -27,47 +27,62 @@
@implementation UIView (XLFormAdditions)
+ (id)autolayoutView
+ (instancetype)autolayoutView
{
UIView *view = [self new];
__kindof UIView *view = [self new];
view.translatesAutoresizingMaskIntoConstraints = NO;
return view;
}
-(NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view
- (NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view
{
return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
return [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeHeight
multiplier:1.0
constant:0.0];
}
- (UIView *)findFirstResponder
{
UIView *firstResponder = nil;
if (self.isFirstResponder) {
return self;
firstResponder = self;
}
for (UIView *subView in self.subviews) {
UIView *firstResponder = [subView findFirstResponder];
if (firstResponder != nil) {
return firstResponder;
else {
for (UIView *subView in self.subviews) {
UIView *fr = [subView findFirstResponder];
if (fr != nil) {
firstResponder = fr;
break;
}
}
}
return nil;
return firstResponder;
}
- (UITableViewCell<XLFormDescriptorCell> *)formDescriptorCell
{
UITableViewCell<XLFormDescriptorCell> * tableViewCell = nil;
if ([self isKindOfClass:[UITableViewCell class]]) {
if ([self conformsToProtocol:@protocol(XLFormDescriptorCell)]){
return (UITableViewCell<XLFormDescriptorCell> *)self;
}
return nil;
}
if (self.superview) {
UITableViewCell<XLFormDescriptorCell> * tableViewCell = [self.superview formDescriptorCell];
if (tableViewCell != nil) {
return tableViewCell;
tableViewCell = (UITableViewCell<XLFormDescriptorCell> *)self;
}
}
return nil;
else if (self.superview) {
UITableViewCell<XLFormDescriptorCell> * cell = [self.superview formDescriptorCell];
if (cell != nil) {
tableViewCell = cell;
}
}
return tableViewCell;
}
@end
@@ -27,7 +27,7 @@
@implementation XLFormRightDetailCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
return [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier];
}
@@ -27,8 +27,8 @@
@interface XLFormRowNavigationAccessoryView : UIToolbar
@property (nonatomic) UIBarButtonItem *previousButton;
@property (nonatomic) UIBarButtonItem *nextButton;
@property (nonatomic) UIBarButtonItem *doneButton;
@property (nonatomic, weak) UIBarButtonItem *previousButton;
@property (nonatomic, weak) UIBarButtonItem *nextButton;
@property (nonatomic, weak) UIBarButtonItem *doneButton;
@end
@@ -25,14 +25,6 @@
#import "XLFormRowNavigationAccessoryView.h"
@interface XLFormRowNavigationAccessoryView ()
@property (nonatomic) UIBarButtonItem *fixedSpace;
@property (nonatomic) UIBarButtonItem *flexibleSpace;
@end
@implementation XLFormRowNavigationAccessoryView
@synthesize previousButton = _previousButton;
@@ -40,59 +32,34 @@
@synthesize doneButton = _doneButton;
- (id)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44.0)];
if (self) {
UIBarButtonItem *previousButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:105 target:nil action:nil];
_previousButton = previousButton;
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:106 target:nil action:nil];
_nextButton = nextButton;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:nil action:nil];
_doneButton = doneButton;
UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedSpace.width = 22.0;
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
self.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth);
NSArray * items = [NSArray arrayWithObjects:self.previousButton,
self.fixedSpace,
self.nextButton,
self.flexibleSpace,
self.doneButton, nil];
NSArray * items = [NSArray arrayWithObjects:previousButton,
fixedSpace,
nextButton,
flexibleSpace,
doneButton, nil];
[self setItems:items];
}
return self;
}
#pragma mark - Properties
-(UIBarButtonItem *)previousButton
{
if (_previousButton) return _previousButton;
_previousButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:105 target:nil action:nil];
return _previousButton;
}
-(UIBarButtonItem *)fixedSpace
{
if (_fixedSpace) return _fixedSpace;
_fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
_fixedSpace.width = 22.0;
return _fixedSpace;
}
-(UIBarButtonItem *)nextButton
{
if (_nextButton) return _nextButton;
_nextButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:106 target:nil action:nil];
return _nextButton;
}
-(UIBarButtonItem *)flexibleSpace
{
if (_flexibleSpace) return _flexibleSpace;
_flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
return _flexibleSpace;
}
-(UIBarButtonItem *)doneButton
{
if (_doneButton) return _doneButton;
_doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:nil action:nil];
return _doneButton;
}
#pragma mark - Helpers
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event
+3 -3
View File
@@ -29,9 +29,9 @@
@interface XLFormTextView : UITextView
@property (nonatomic) NSString *placeholder;
@property (nonatomic) UIColor *placeholderColor;
@property (nonatomic, copy) NSString *placeholder;
@property (nonatomic, copy) UIColor *placeholderColor;
@property (readonly) UILabel *placeHolderLabel;
@property (nonatomic, readonly, weak) UILabel *placeHolderLabel;
@end
+12 -10
View File
@@ -30,10 +30,10 @@
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil];
}
- (id)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame
{
if((self = [super initWithFrame:frame])){
self.scrollsToTop = NO;
@@ -67,17 +67,19 @@
{
if([[self placeholder] length] > 0){
if (_placeHolderLabel == nil ){
_placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(4,8,self.bounds.size.width - 16,0)];
_placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
_placeHolderLabel.numberOfLines = 0;
_placeHolderLabel.backgroundColor = [UIColor clearColor];
_placeHolderLabel.textColor = self.placeholderColor;
_placeHolderLabel.alpha = 0;
_placeHolderLabel.tag = 999;
[self addSubview:_placeHolderLabel];
UILabel *placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(4,8,self.bounds.size.width - 16,0)];
placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
placeHolderLabel.numberOfLines = 0;
placeHolderLabel.backgroundColor = [UIColor clearColor];
placeHolderLabel.textColor = self.placeholderColor;
placeHolderLabel.alpha = 0;
placeHolderLabel.tag = 999;
[self addSubview:placeHolderLabel];
_placeHolderLabel = placeHolderLabel;
}
_placeHolderLabel.text = self.placeholder;
_placeHolderLabel.font = self.font;
_placeHolderLabel.textColor = self.placeholderColor;
[_placeHolderLabel sizeToFit];
[self sendSubviewToBack:_placeHolderLabel];
}
+3 -3
View File
@@ -29,10 +29,10 @@
@interface XLFormRegexValidator : XLFormValidator
@property NSString *msg;
@property NSString *regex;
@property (nonatomic, copy) NSString *msg;
@property (nonatomic, copy) NSString *regex;
- (id)initWithMsg:(NSString*)msg andRegexString:(NSString*)regex;
- (instancetype)initWithMsg:(NSString*)msg andRegexString:(NSString*)regex;
+ (XLFormRegexValidator *)formRegexValidatorWithMsg:(NSString *)msg regex:(NSString *)regex;
@end
+1 -1
View File
@@ -27,7 +27,7 @@
@implementation XLFormRegexValidator
-(id)initWithMsg:(NSString*)msg andRegexString:(NSString*)regex {
-(instancetype)initWithMsg:(NSString*)msg andRegexString:(NSString*)regex {
self = [super init];
if (self) {
self.msg = msg;
@@ -29,12 +29,12 @@
@interface XLFormValidationStatus : NSObject
@property NSString *msg;
@property BOOL isValid;
@property (nonatomic, copy) NSString *msg;
@property (nonatomic, assign) BOOL isValid;
@property (nonatomic, weak) XLFormRowDescriptor *rowDescriptor;
//-(id)initWithMsg:(NSString*)msg andStatus:(BOOL)isValid;
-(id)initWithMsg:(NSString*)msg status:(BOOL)isValid rowDescriptor:(XLFormRowDescriptor *)row;
//-(instancetype)initWithMsg:(NSString*)msg andStatus:(BOOL)isValid;
-(instancetype)initWithMsg:(NSString*)msg status:(BOOL)isValid rowDescriptor:(XLFormRowDescriptor *)row;
//+(XLFormValidationStatus *)formValidationStatusWithMsg:(NSString *)msg status:(BOOL)status;
+(XLFormValidationStatus *)formValidationStatusWithMsg:(NSString *)msg status:(BOOL)status rowDescriptor:(XLFormRowDescriptor *)row;
@@ -27,11 +27,11 @@
@implementation XLFormValidationStatus
-(id)initWithMsg:(NSString*)msg andStatus:(BOOL)isValid {
-(instancetype)initWithMsg:(NSString*)msg andStatus:(BOOL)isValid {
return [self initWithMsg:msg status:isValid rowDescriptor:nil];
}
-(id)initWithMsg:(NSString*)msg status:(BOOL)isValid rowDescriptor:(XLFormRowDescriptor *)row {
-(instancetype)initWithMsg:(NSString*)msg status:(BOOL)isValid rowDescriptor:(XLFormRowDescriptor *)row {
self = [super init];
if (self) {
self.msg = msg;