From e858b730f44d4034b11e1534d7f6c1ede51bb604 Mon Sep 17 00:00:00 2001 From: nongji360 Date: Tue, 11 Apr 2017 15:32:42 +0800 Subject: [PATCH 01/27] selectorCell display repair Unable to display when value than apples first selectorOptions --- XLForm/XL/Cell/XLFormSelectorCell.m | 96 +++++++++++++++++------------ 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/XLForm/XL/Cell/XLFormSelectorCell.m b/XLForm/XL/Cell/XLFormSelectorCell.m index edc9112c..ff0eaff7 100644 --- a/XLForm/XL/Cell/XLFormSelectorCell.m +++ b/XLForm/XL/Cell/XLFormSelectorCell.m @@ -58,19 +58,33 @@ -(NSString *)valueDisplayText } } NSMutableArray * descriptionArray = [NSMutableArray arrayWithCapacity:[self.rowDescriptor.value count]]; - for (id option in self.rowDescriptor.selectorOptions) { - NSArray * selectedValues = self.rowDescriptor.value; - if ([selectedValues formIndexForItem:option] != NSNotFound){ - 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 * tranformedValue = [valueTransformer transformedValue:option]; - if (tranformedValue){ - [descriptionArray addObject:tranformedValue]; + //add by OE Ex: value taken form the lacal cache but selectorOptions in the networking + if (self.rowDescriptor.selectorOptions.count>0){ + + for (id option in self.rowDescriptor.selectorOptions) { + NSArray * selectedValues = self.rowDescriptor.value; + if ([selectedValues formIndexForItem:option] != NSNotFound){ + 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 * tranformedValue = [valueTransformer transformedValue:option]; + if (tranformedValue){ + [descriptionArray addObject:tranformedValue]; + } + } + else{ + [descriptionArray addObject:[option displayText]]; } } - else{ - [descriptionArray addObject:[option displayText]]; + } + }else{ + for (id option in self.rowDescriptor.value) { + if ([option isKindOfClass:[XLFormOptionsObject class]]) { + XLFormOptionsObject *newOption = (XLFormOptionsObject*)option; + [descriptionArray addObject:newOption.formDisplayText]; + } + else { + [descriptionArray addObject:[NSString stringWithFormat:@"%@",option]]; } } } @@ -166,7 +180,7 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c UIViewController *selectorViewController = (UIViewController *)controllerToPresent; selectorViewController.rowDescriptor = self.rowDescriptor; selectorViewController.title = self.rowDescriptor.selectorTitle; - + if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) { if (self.popoverController && self.popoverController.popoverVisible) { [self.popoverController dismissPopoverAnimated:NO]; @@ -192,9 +206,9 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c XLFormOptionsViewController * optionsViewController = [[XLFormOptionsViewController alloc] initWithStyle:UITableViewStyleGrouped titleHeaderSection:nil titleFooterSection:nil]; optionsViewController.rowDescriptor = self.rowDescriptor; optionsViewController.title = self.rowDescriptor.selectorTitle; - - if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) { - self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController]; + + if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorPopover]) { + self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController]; self.popoverController.delegate = self; optionsViewController.popoverController = self.popoverController; if (self.detailTextLabel.window){ @@ -204,9 +218,9 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c [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]; - } else { - [controller.navigationController pushViewController:optionsViewController animated:YES]; - } + } else { + [controller.navigationController pushViewController:optionsViewController animated:YES]; + } } } else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelector] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) @@ -221,7 +235,7 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c } optionsViewController.rowDescriptor = self.rowDescriptor; optionsViewController.title = self.rowDescriptor.selectorTitle; - + if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeMultipleSelectorPopover]) { self.popoverController = [[UIPopoverController alloc] initWithContentViewController:optionsViewController]; self.popoverController.delegate = self; @@ -238,8 +252,8 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c } } else if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeSelectorActionSheet]){ - - + + #if __IPHONE_OS_VERSION_MAX_ALLOWED < 80000 UIActionSheet * actionSheet = [[UIActionSheet alloc] initWithTitle:self.rowDescriptor.selectorTitle delegate:self @@ -266,15 +280,15 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c alertController.popoverPresentationController.sourceRect = [formViewController.tableView convertRect:v.frame fromView:self]; __weak __typeof(self)weakSelf = self; for (id option in self.rowDescriptor.selectorOptions) { - 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; - } - } + 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; + } + } [alertController addAction:[UIAlertAction actionWithTitle:optionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { @@ -303,7 +317,7 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c [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 @@ -334,7 +348,7 @@ -(void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)c style:UIAlertActionStyleCancel handler:nil]]; [controller presentViewController:alertController animated:YES completion:nil]; - + } #ifndef XL_APP_EXTENSIONS else{ @@ -417,15 +431,15 @@ - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)butto - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { - 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 * tranformedValue = [valueTransformer transformedValue:[[self.rowDescriptor.selectorOptions objectAtIndex:row] valueData]]; - if (tranformedValue){ - return tranformedValue; - } - } - return [[self.rowDescriptor.selectorOptions objectAtIndex:row] 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 * tranformedValue = [valueTransformer transformedValue:[[self.rowDescriptor.selectorOptions objectAtIndex:row] valueData]]; + if (tranformedValue){ + return tranformedValue; + } + } + return [[self.rowDescriptor.selectorOptions objectAtIndex:row] displayText]; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component From bfe653f6b9dc7fae9620947672a648ceedf32373 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 10:36:40 +0300 Subject: [PATCH 02/27] fixed crash --- XLForm/XL/Cell/XLFormSelectorCell.m | 36 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/XLForm/XL/Cell/XLFormSelectorCell.m b/XLForm/XL/Cell/XLFormSelectorCell.m index b0c9cd90..5b51f504 100644 --- a/XLForm/XL/Cell/XLFormSelectorCell.m +++ b/XLForm/XL/Cell/XLFormSelectorCell.m @@ -57,19 +57,33 @@ -(NSString *)valueDisplayText } } NSMutableArray * descriptionArray = [NSMutableArray arrayWithCapacity:[self.rowDescriptor.value count]]; - for (id option in self.rowDescriptor.selectorOptions) { - NSArray * selectedValues = self.rowDescriptor.value; - if ([selectedValues formIndexForItem:option] != NSNotFound){ - 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 * tranformedValue = [valueTransformer transformedValue:option]; - if (tranformedValue){ - [descriptionArray addObject:tranformedValue]; + //add by OE Ex: value taken form the lacal cache but selectorOptions in the networking + if (self.rowDescriptor.selectorOptions.count>0){ + + for (id option in self.rowDescriptor.selectorOptions) { + NSArray * selectedValues = self.rowDescriptor.value; + if ([selectedValues formIndexForItem:option] != NSNotFound){ + 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 * tranformedValue = [valueTransformer transformedValue:option]; + if (tranformedValue){ + [descriptionArray addObject:tranformedValue]; + } + } + else{ + [descriptionArray addObject:[option displayText]]; } } - else{ - [descriptionArray addObject:[option displayText]]; + } + }else{ + for (id option in self.rowDescriptor.value) { + if ([option isKindOfClass:[XLFormOptionsObject class]]) { + XLFormOptionsObject *newOption = (XLFormOptionsObject*)option; + [descriptionArray addObject:newOption.formDisplayText]; + } + else { + [descriptionArray addObject:[NSString stringWithFormat:@"%@",option]]; } } } From a6dd439bfd8305cbf3bfeb634bd919d7dc234f6a Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 10:38:32 +0300 Subject: [PATCH 03/27] fixed memory leaks --- XLForm.xcodeproj/project.pbxproj | 6 +++++- XLForm.xcodeproj/xcshareddata/xcschemes/XLForm.xcscheme | 4 +--- XLForm/XL/Cell/XLFormImageCell.m | 2 +- XLForm/XL/Descriptors/XLFormRowDescriptor.m | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/XLForm.xcodeproj/project.pbxproj b/XLForm.xcodeproj/project.pbxproj index ad0b977b..e082eb0d 100644 --- a/XLForm.xcodeproj/project.pbxproj +++ b/XLForm.xcodeproj/project.pbxproj @@ -414,7 +414,7 @@ E267FD171BE8048900F86B42 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = XLForm; TargetAttributes = { E267FD1F1BE8048900F86B42 = { @@ -509,12 +509,14 @@ 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; @@ -564,12 +566,14 @@ 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; diff --git a/XLForm.xcodeproj/xcshareddata/xcschemes/XLForm.xcscheme b/XLForm.xcodeproj/xcshareddata/xcschemes/XLForm.xcscheme index 1c1c2367..20fc64ab 100644 --- a/XLForm.xcodeproj/xcshareddata/xcschemes/XLForm.xcscheme +++ b/XLForm.xcodeproj/xcshareddata/xcschemes/XLForm.xcscheme @@ -1,6 +1,6 @@ @@ -37,7 +36,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/XLForm/XL/Cell/XLFormImageCell.m b/XLForm/XL/Cell/XLFormImageCell.m index 25de18c7..2fe970bb 100644 --- a/XLForm/XL/Cell/XLFormImageCell.m +++ b/XLForm/XL/Cell/XLFormImageCell.m @@ -100,7 +100,7 @@ - (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *) } dispatch_async(dispatch_get_main_queue(), ^{ - [self.formViewController presentViewController:alertController animated: true completion: nil]; + [self.formViewController presentViewController:self->alertController animated: true completion: nil]; }); } diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index af0a959a..213b0d51 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -155,7 +155,7 @@ -(XLFormBaseCell *)cellForFormController:(XLFormViewController * __unused)formCo - (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]; }]; } From 05506d2d45835e2dc16eb1d92ad1aa0d955665c1 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 10:40:59 +0300 Subject: [PATCH 04/27] Cell disappears while inline picker is open --- XLForm/XL/Cell/XLFormDateCell.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/XLForm/XL/Cell/XLFormDateCell.m b/XLForm/XL/Cell/XLFormDateCell.m index 5821fcd7..25947aa8 100644 --- a/XLForm/XL/Cell/XLFormDateCell.m +++ b/XLForm/XL/Cell/XLFormDateCell.m @@ -95,11 +95,10 @@ -(BOOL)resignFirstResponder NSIndexPath * selectedRowPath = [self.formViewController.form indexPathOfFormRow:self.rowDescriptor]; NSIndexPath * nextRowPath = [NSIndexPath indexPathForRow:selectedRowPath.row + 1 inSection:selectedRowPath.section]; XLFormRowDescriptor * nextFormRow = [self.formViewController.form formRowAtIndex:nextRowPath]; - BOOL result = [super resignFirstResponder]; if ([nextFormRow.rowType isEqualToString:XLFormRowDescriptorTypeDatePicker]){ [self.rowDescriptor.sectionDescriptor removeFormRow:nextFormRow]; } - return result; + return [super resignFirstResponder]; } return [super resignFirstResponder]; } From b3fbb31767d9cd9475e9b31f569396eb4b7ad26a Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 10:44:01 +0300 Subject: [PATCH 05/27] Fixes crash on update --- XLForm/XL/Controllers/XLFormViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 97180101..8755f0dc 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -314,8 +314,8 @@ -(void)formRowDescriptorPredicateHasChanged:(XLFormRowDescriptor *)formRow oldVa -(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]; From 647c33486b08b80dd925034444fb4114de74cbcd Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 10:50:41 +0300 Subject: [PATCH 06/27] check object object equal --- XLForm/XL/Controllers/XLFormOptionsObject.m | 5 +++++ XLForm/XL/Helpers/NSObject+XLFormAdditions.m | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/XLForm/XL/Controllers/XLFormOptionsObject.m b/XLForm/XL/Controllers/XLFormOptionsObject.m index 05deb252..7ff7f393 100644 --- a/XLForm/XL/Controllers/XLFormOptionsObject.m +++ b/XLForm/XL/Controllers/XLFormOptionsObject.m @@ -107,4 +107,9 @@ -(instancetype)initWithCoder:(NSCoder *)decoder } +-(NSUInteger)hash +{ + return [[self formValue ] hash]; +} + @end diff --git a/XLForm/XL/Helpers/NSObject+XLFormAdditions.m b/XLForm/XL/Helpers/NSObject+XLFormAdditions.m index 13b6214e..f63361c9 100644 --- a/XLForm/XL/Helpers/NSObject+XLFormAdditions.m +++ b/XLForm/XL/Helpers/NSObject+XLFormAdditions.m @@ -53,7 +53,7 @@ -(id)valueData return result; } if ([self conformsToProtocol:@protocol(XLFormOptionObject)]){ - return [(id)self formValue]; + return (id)self; } return nil; } From 5ffb4e6bf00e99c17d103d5c69dd9c19d2b12727 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 1 Aug 2018 11:19:18 +0300 Subject: [PATCH 07/27] codereview --- Examples/Objective-C/Podfile.lock | 13 +++++-- .../XLForm.xcodeproj/project.pbxproj | 24 +++--------- .../AppIcon.appiconset/Contents.json | 39 ++++++++++++++++++- XLForm/XL/Cell/XLFormTextFieldCell.m | 10 ++--- XLForm/XL/Cell/XLFormTextViewCell.m | 4 +- XLForm/XL/Descriptors/XLFormDescriptor.m | 2 +- XLForm/XL/Descriptors/XLFormRowDescriptor.m | 8 ++-- .../XL/Descriptors/XLFormSectionDescriptor.m | 4 +- 8 files changed, 67 insertions(+), 37 deletions(-) diff --git a/Examples/Objective-C/Podfile.lock b/Examples/Objective-C/Podfile.lock index daedd938..61d25068 100644 --- a/Examples/Objective-C/Podfile.lock +++ b/Examples/Objective-C/Podfile.lock @@ -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: 04110197c12187dd28a6c7295d3d8b95f4fdb4de + XLForm: c173e0476a302add7753520d4ab4f18f3eb47ea3 PODFILE CHECKSUM: 64fbcd03a2c13762b2c18e3938cc8008807937c9 -COCOAPODS: 1.3.1 +COCOAPODS: 1.5.3 diff --git a/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj b/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj index 5113bf54..33a78e9e 100644 --- a/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj +++ b/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj @@ -486,7 +486,6 @@ 2850C5F418D0F706002B7D0A /* Sources */, 2850C5F518D0F706002B7D0A /* Frameworks */, 2850C5F618D0F706002B7D0A /* Resources */, - 32EB30E0A90A4E91864B1D3C /* [CP] Embed Pods Frameworks */, DE3D12F5596780A66C6C3D4A /* [CP] Copy Pods Resources */, ); buildRules = ( @@ -504,7 +503,7 @@ 2850C5F018D0F706002B7D0A /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = Xmartlabs; }; buildConfigurationList = 2850C5F318D0F706002B7D0A /* Build configuration list for PBXProject "XLForm" */; @@ -542,21 +541,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 32EB30E0A90A4E91864B1D3C /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; DE3D12F5596780A66C6C3D4A /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -568,7 +552,7 @@ ); name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/XLForm.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -668,12 +652,14 @@ 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; @@ -718,12 +704,14 @@ 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; diff --git a/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json b/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json index ce597e2c..a57a9fd1 100644 --- a/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json @@ -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" }, { @@ -158,6 +183,16 @@ "scale" : "2x", "role" : "quickLook", "subtype" : "42mm" + }, + { + "idiom" : "watch-marketing", + "size" : "1024x1024", + "scale" : "1x" + }, + { + "idiom" : "car", + "size" : "120x120", + "scale" : "1x" } ], "info" : { diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index 556493c4..486ff229 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -225,10 +225,10 @@ -(void)updateConstraints 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{ @@ -240,10 +240,10 @@ -(void)updateConstraints 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{ @@ -279,7 +279,7 @@ - (BOOL)textFieldShouldEndEditing:(UITextField *)textField } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - if (self.textFieldMaxNumberOfCharacters) { + if (self.textFieldMaxNumberOfCharacters != nil) { // Check maximum length requirement NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string]; if (newString.length > self.textFieldMaxNumberOfCharacters.integerValue) { diff --git a/XLForm/XL/Cell/XLFormTextViewCell.m b/XLForm/XL/Cell/XLFormTextViewCell.m index b02c14b6..1388aeb1 100644 --- a/XLForm/XL/Cell/XLFormTextViewCell.m +++ b/XLForm/XL/Cell/XLFormTextViewCell.m @@ -160,7 +160,7 @@ -(void)updateConstraints } 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,7 +207,7 @@ -(void)textViewDidChange:(UITextView *)textView{ } - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { - if (self.textViewMaxNumberOfCharacters) { + if (self.textViewMaxNumberOfCharacters != nil) { // Check maximum length requirement NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text]; if (newText.length > self.textViewMaxNumberOfCharacters.integerValue) { diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.m b/XLForm/XL/Descriptors/XLFormDescriptor.m index 1b6926c7..f7036668 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormDescriptor.m @@ -86,7 +86,7 @@ -(instancetype)initWithTitle:(NSString *)title; +(instancetype)formDescriptor { - return [[self class] formDescriptorWithTitle:nil]; + return [[self class] formDescriptorWithTitle:@""]; } +(instancetype)formDescriptorWithTitle:(NSString *)title diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index 213b0d51..bfe90e60 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -387,9 +387,9 @@ -(id)disabled -(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; } } @@ -408,9 +408,9 @@ -(NSNumber *)hidePredicateCache -(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; } } diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index e51e7e52..88aa4d6f 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -342,9 +342,9 @@ -(NSNumber *)hidePredicateCache -(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; } } From d17ba20cbcce5e491905bd9f1f92bf4f7aa72bb1 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Thu, 13 Dec 2018 11:38:37 +0200 Subject: [PATCH 08/27] fixed memory leaks --- .../Formatters/FormattersViewController.m | 4 +- .../XLFormInlineSegmentedCell.m | 5 +- .../AppIcon.appiconset/Contents.json | 25 ++++++- XLForm/XL/Cell/XLFormBaseCell.h | 4 +- XLForm/XL/Cell/XLFormDateCell.h | 10 +-- XLForm/XL/Cell/XLFormDateCell.m | 4 +- XLForm/XL/Cell/XLFormImageCell.m | 7 +- XLForm/XL/Cell/XLFormInlineSelectorCell.m | 4 +- XLForm/XL/Cell/XLFormLeftRightSelectorCell.m | 8 +-- XLForm/XL/Cell/XLFormPickerCell.h | 2 +- XLForm/XL/Cell/XLFormPickerCell.m | 20 +++--- XLForm/XL/Cell/XLFormSegmentedCell.m | 2 +- XLForm/XL/Cell/XLFormTextFieldCell.h | 8 +-- XLForm/XL/Cell/XLFormTextFieldCell.m | 28 +++----- XLForm/XL/Cell/XLFormTextViewCell.h | 8 +-- XLForm/XL/Cell/XLFormTextViewCell.m | 26 +++---- XLForm/XL/Controllers/XLFormOptionsObject.h | 4 +- XLForm/XL/Controllers/XLFormOptionsObject.m | 2 +- .../Controllers/XLFormOptionsViewController.m | 4 +- .../XLFormRowDescriptorViewController.h | 2 +- XLForm/XL/Controllers/XLFormViewController.h | 4 +- XLForm/XL/Controllers/XLFormViewController.m | 44 +++++++----- XLForm/XL/Descriptors/XLFormDescriptor.h | 18 ++--- XLForm/XL/Descriptors/XLFormDescriptor.m | 19 ++--- XLForm/XL/Descriptors/XLFormRowDescriptor.h | 72 +++++++++---------- XLForm/XL/Descriptors/XLFormRowDescriptor.m | 14 ++-- .../XL/Descriptors/XLFormSectionDescriptor.h | 20 +++--- .../XL/Descriptors/XLFormSectionDescriptor.m | 10 +-- XLForm/XL/Helpers/Views/XLFormTextView.h | 6 +- XLForm/XL/Helpers/Views/XLFormTextView.m | 17 ++--- XLForm/XL/Validation/XLFormRegexValidator.h | 4 +- XLForm/XL/Validation/XLFormValidationStatus.h | 4 +- 32 files changed, 209 insertions(+), 200 deletions(-) diff --git a/Examples/Objective-C/Examples/Formatters/FormattersViewController.m b/Examples/Objective-C/Examples/Formatters/FormattersViewController.m index 47e7bde4..14bf87a0 100644 --- a/Examples/Objective-C/Examples/Formatters/FormattersViewController.m +++ b/Examples/Objective-C/Examples/Formatters/FormattersViewController.m @@ -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 @@ -117,4 +117,4 @@ -(id)init } -@end \ No newline at end of file +@end diff --git a/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m b/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m index 767d7adc..1b7b30c9 100644 --- a/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m +++ b/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m @@ -26,10 +26,11 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { + BOOL result = [super becomeFirstResponder]; if (self.isFirstResponder){ - return [super becomeFirstResponder]; + return result; } - BOOL result = [super becomeFirstResponder]; + if (result){ XLFormRowDescriptor * inlineRowDescriptor = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:[XLFormViewController inlineRowDescriptorTypesForRowDescriptorTypes][self.rowDescriptor.rowType]]; UITableViewCell * cell = [inlineRowDescriptor cellForFormController:self.formViewController]; diff --git a/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json b/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json index a57a9fd1..a76f48d9 100644 --- a/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Examples/Objective-C/XLForm/Images.xcassets/AppIcon.appiconset/Contents.json @@ -167,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", @@ -184,6 +191,13 @@ "role" : "quickLook", "subtype" : "42mm" }, + { + "size" : "108x108", + "idiom" : "watch", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "44mm" + }, { "idiom" : "watch-marketing", "size" : "1024x1024", @@ -193,6 +207,13 @@ "idiom" : "car", "size" : "120x120", "scale" : "1x" + }, + { + "size" : "44x44", + "idiom" : "watch", + "scale" : "2x", + "role" : "longLook", + "subtype" : "42mm" } ], "info" : { diff --git a/XLForm/XL/Cell/XLFormBaseCell.h b/XLForm/XL/Cell/XLFormBaseCell.h index 591907a0..a11ba2cb 100644 --- a/XLForm/XL/Cell/XLFormBaseCell.h +++ b/XLForm/XL/Cell/XLFormBaseCell.h @@ -42,8 +42,8 @@ @protocol XLFormReturnKeyProtocol -@property UIReturnKeyType returnKeyType; -@property UIReturnKeyType nextReturnKeyType; +@property (nonatomic, assign) UIReturnKeyType returnKeyType; +@property (nonatomic, assign) UIReturnKeyType nextReturnKeyType; @end diff --git a/XLForm/XL/Cell/XLFormDateCell.h b/XLForm/XL/Cell/XLFormDateCell.h index de8f2a96..da53e81d 100644 --- a/XLForm/XL/Cell/XLFormDateCell.h +++ b/XLForm/XL/Cell/XLFormDateCell.h @@ -34,10 +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) NSLocale *locale; +@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 diff --git a/XLForm/XL/Cell/XLFormDateCell.m b/XLForm/XL/Cell/XLFormDateCell.m index 25947aa8..beae02bb 100644 --- a/XLForm/XL/Cell/XLFormDateCell.m +++ b/XLForm/XL/Cell/XLFormDateCell.m @@ -60,11 +60,11 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { + BOOL result = [super becomeFirstResponder]; if (self.isFirstResponder){ - return [super becomeFirstResponder]; + return result; } _beforeChangeColor = self.detailTextLabel.textColor; - BOOL result = [super becomeFirstResponder]; if (result){ if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTimeInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateTimeInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimerInline]) { diff --git a/XLForm/XL/Cell/XLFormImageCell.m b/XLForm/XL/Cell/XLFormImageCell.m index 2fe970bb..3ce8ddf8 100644 --- a/XLForm/XL/Cell/XLFormImageCell.m +++ b/XLForm/XL/Cell/XLFormImageCell.m @@ -71,6 +71,7 @@ - (UIImageView *)imageView - (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *)controller { + __weak typeof(self) weak = self; alertController = [UIAlertController alertControllerWithTitle: self.rowDescriptor.title message: nil preferredStyle: UIAlertControllerStyleActionSheet]; @@ -78,14 +79,14 @@ - (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *) [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]; }]]; } @@ -100,7 +101,7 @@ - (void)formDescriptorCellDidSelectedWithFormController:(XLFormViewController *) } dispatch_async(dispatch_get_main_queue(), ^{ - [self.formViewController presentViewController:self->alertController animated: true completion: nil]; + [weak.formViewController presentViewController:self->alertController animated: true completion: nil]; }); } diff --git a/XLForm/XL/Cell/XLFormInlineSelectorCell.m b/XLForm/XL/Cell/XLFormInlineSelectorCell.m index 48b96836..c2cb15e9 100644 --- a/XLForm/XL/Cell/XLFormInlineSelectorCell.m +++ b/XLForm/XL/Cell/XLFormInlineSelectorCell.m @@ -42,11 +42,11 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { + BOOL result = [super becomeFirstResponder]; if (self.isFirstResponder){ - return [super becomeFirstResponder]; + return result; } _beforeChangeColor = self.detailTextLabel.textColor; - BOOL result = [super becomeFirstResponder]; if (result){ XLFormRowDescriptor * inlineRowDescriptor = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:[XLFormViewController inlineRowDescriptorTypesForRowDescriptorTypes][self.rowDescriptor.rowType]]; UITableViewCell * cell = [inlineRowDescriptor cellForFormController:self.formViewController]; diff --git a/XLForm/XL/Cell/XLFormLeftRightSelectorCell.m b/XLForm/XL/Cell/XLFormLeftRightSelectorCell.m index ab7d44e3..9cd497ad 100644 --- a/XLForm/XL/Cell/XLFormLeftRightSelectorCell.m +++ b/XLForm/XL/Cell/XLFormLeftRightSelectorCell.m @@ -196,14 +196,14 @@ -(void)leftButtonPressed:(UIButton *)leftButton [alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]]; - __weak __typeof(self)weakSelf = self; + __weak typeof(self) weak = 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]; + weak.rowDescriptor.value = [weak chooseNewRightValueFromOption:leftOption]; + weak.rowDescriptor.leftRightSelectorLeftOptionSelected = [weak leftOptionForDescription:[leftOption.leftValue displayText]].leftValue; + [weak.formViewController updateFormRow:weak.rowDescriptor]; }]]; } diff --git a/XLForm/XL/Cell/XLFormPickerCell.h b/XLForm/XL/Cell/XLFormPickerCell.h index 3b2194a2..d238ee4a 100644 --- a/XLForm/XL/Cell/XLFormPickerCell.h +++ b/XLForm/XL/Cell/XLFormPickerCell.h @@ -28,6 +28,6 @@ @interface XLFormPickerCell : XLFormBaseCell -@property (nonatomic) UIPickerView * pickerView; +@property (nonatomic, weak) UIPickerView * pickerView; @end diff --git a/XLForm/XL/Cell/XLFormPickerCell.m b/XLForm/XL/Cell/XLFormPickerCell.m index fed9dc17..cfe4a3a8 100644 --- a/XLForm/XL/Cell/XLFormPickerCell.m +++ b/XLForm/XL/Cell/XLFormPickerCell.m @@ -56,23 +56,19 @@ -(BOOL)canBecomeFirstResponder 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}]]; } diff --git a/XLForm/XL/Cell/XLFormSegmentedCell.m b/XLForm/XL/Cell/XLFormSegmentedCell.m index cb965084..d33db2ea 100644 --- a/XLForm/XL/Cell/XLFormSegmentedCell.m +++ b/XLForm/XL/Cell/XLFormSegmentedCell.m @@ -30,7 +30,7 @@ @interface XLFormSegmentedCell() -@property NSMutableArray * dynamicCustomConstraints; +@property (nonatomic, strong) NSMutableArray * dynamicCustomConstraints; @end diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.h b/XLForm/XL/Cell/XLFormTextFieldCell.h index 4e625010..19294bdf 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.h +++ b/XLForm/XL/Cell/XLFormTextFieldCell.h @@ -31,10 +31,10 @@ extern NSString *const XLFormTextFieldMaxNumberOfCharacters; @interface XLFormTextFieldCell : XLFormBaseCell -@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) NSNumber *textFieldMaxNumberOfCharacters; +@property (nonatomic, copy) NSNumber *textFieldLengthPercentage; +@property (nonatomic, copy) NSNumber *textFieldMaxNumberOfCharacters; @end diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index 486ff229..46ba126e 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -34,7 +34,7 @@ @interface XLFormTextFieldCell() -@property NSMutableArray * dynamicCustomConstraints; +@property (nonatomic, strong) NSMutableArray * dynamicCustomConstraints; @end @@ -79,8 +79,14 @@ -(void)configure { [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]; @@ -176,22 +182,6 @@ -(void)unhighlight [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 diff --git a/XLForm/XL/Cell/XLFormTextViewCell.h b/XLForm/XL/Cell/XLFormTextViewCell.h index 84f1620f..7f6e4f06 100644 --- a/XLForm/XL/Cell/XLFormTextViewCell.h +++ b/XLForm/XL/Cell/XLFormTextViewCell.h @@ -33,10 +33,10 @@ 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) NSNumber *textViewMaxNumberOfCharacters; +@property (nonatomic, copy) NSNumber *textViewLengthPercentage; +@property (nonatomic, copy) NSNumber *textViewMaxNumberOfCharacters; @end diff --git a/XLForm/XL/Cell/XLFormTextViewCell.m b/XLForm/XL/Cell/XLFormTextViewCell.m index 1388aeb1..abbe6b73 100644 --- a/XLForm/XL/Cell/XLFormTextViewCell.m +++ b/XLForm/XL/Cell/XLFormTextViewCell.m @@ -70,34 +70,26 @@ -(void)dealloc #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]]; diff --git a/XLForm/XL/Controllers/XLFormOptionsObject.h b/XLForm/XL/Controllers/XLFormOptionsObject.h index de2382b4..4cd69b05 100644 --- a/XLForm/XL/Controllers/XLFormOptionsObject.h +++ b/XLForm/XL/Controllers/XLFormOptionsObject.h @@ -28,8 +28,8 @@ @interface XLFormOptionsObject : NSObject -@property (nonatomic) NSString * formDisplaytext; -@property (nonatomic) id formValue; +@property (nonatomic, copy) NSString * formDisplaytext; +@property (nonatomic, strong) id formValue; +(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText; +(XLFormOptionsObject *)formOptionsOptionForValue:(id)value fromOptions:(NSArray *)options; diff --git a/XLForm/XL/Controllers/XLFormOptionsObject.m b/XLForm/XL/Controllers/XLFormOptionsObject.m index 7ff7f393..a029ef1d 100644 --- a/XLForm/XL/Controllers/XLFormOptionsObject.m +++ b/XLForm/XL/Controllers/XLFormOptionsObject.m @@ -29,7 +29,7 @@ @implementation XLFormOptionsObject +(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText { - return [[XLFormOptionsObject alloc] initWithValue:value displayText:displayText]; + return [[self alloc] initWithValue:value displayText:displayText]; } -(instancetype)initWithValue:(id)value displayText:(NSString *)displayText diff --git a/XLForm/XL/Controllers/XLFormOptionsViewController.m b/XLForm/XL/Controllers/XLFormOptionsViewController.m index c8524394..a40e9e33 100644 --- a/XLForm/XL/Controllers/XLFormOptionsViewController.m +++ b/XLForm/XL/Controllers/XLFormOptionsViewController.m @@ -34,8 +34,8 @@ @interface XLFormOptionsViewController () -@property NSString * titleHeaderSection; -@property NSString * titleFooterSection; +@property (nonatomic, copy) NSString * titleHeaderSection; +@property (nonatomic, copy) NSString * titleFooterSection; @end diff --git a/XLForm/XL/Controllers/XLFormRowDescriptorViewController.h b/XLForm/XL/Controllers/XLFormRowDescriptorViewController.h index 2bfff341..1ad8944a 100644 --- a/XLForm/XL/Controllers/XLFormRowDescriptorViewController.h +++ b/XLForm/XL/Controllers/XLFormRowDescriptorViewController.h @@ -30,6 +30,6 @@ @protocol XLFormRowDescriptorViewController @required -@property (nonatomic) XLFormRowDescriptor * rowDescriptor; +@property (nonatomic, weak) XLFormRowDescriptor * rowDescriptor; @end diff --git a/XLForm/XL/Controllers/XLFormViewController.h b/XLForm/XL/Controllers/XLFormViewController.h index 82293dd6..d93fab8b 100644 --- a/XLForm/XL/Controllers/XLFormViewController.h +++ b/XLForm/XL/Controllers/XLFormViewController.h @@ -81,8 +81,8 @@ typedef NS_ENUM(NSUInteger, XLFormRowNavigationDirection) { @interface XLFormViewController : UIViewController -@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; diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 8755f0dc..6f41ff5d 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -33,7 +33,6 @@ @interface XLFormRowDescriptor(_XLFormViewController) -@property (readonly) NSArray * observers; -(BOOL)evaluateIsDisabled; -(BOOL)evaluateIsHidden; @@ -47,7 +46,7 @@ -(BOOL)evaluateIsHidden; @interface XLFormDescriptor (_XLFormViewController) -@property NSMutableDictionary* rowObservers; +@property (atomic, strong) NSMutableDictionary* rowObservers; @end @@ -57,8 +56,8 @@ @interface XLFormViewController() NSNumber *_oldBottomTableContentInset; CGRect _keyboardFrame; } -@property UITableViewStyle tableViewStyle; -@property (nonatomic) XLFormRowNavigationAccessoryView * navigationAccessoryView; +@property (nonatomic, assign) UITableViewStyle tableViewStyle; +@property (nonatomic, strong) XLFormRowNavigationAccessoryView * navigationAccessoryView; @end @@ -113,16 +112,19 @@ - (void)dealloc - (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; @@ -434,9 +436,10 @@ -(void)multivaluedInsertButtonTapped:(XLFormRowDescriptor *)formRow 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 * cell = (UITableViewCell *)[formRowDescriptor cellForFormController:self]; if ([cell formDescriptorCellCanBecomeFirstResponder]){ @@ -650,9 +653,10 @@ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sou #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; }); } @@ -667,9 +671,10 @@ -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEdi [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 * firstResponderCell = [firstResponder formDescriptorCell]; @@ -686,9 +691,10 @@ -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEdi 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 * cell = (UITableViewCell *)[formRowDescriptor cellForFormController:self]; diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.h b/XLForm/XL/Descriptors/XLFormDescriptor.h index 938382ca..b02ef2e8 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormDescriptor.h @@ -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 (weak, nullable) id delegate; +@property (nonatomic, 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 (nonatomic, weak, nullable) id delegate; +(nonnull instancetype)formDescriptor; +(nonnull instancetype)formDescriptorWithTitle:(nullable NSString *)title; diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.m b/XLForm/XL/Descriptors/XLFormDescriptor.m index f7036668..09279848 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormDescriptor.m @@ -35,7 +35,7 @@ @interface XLFormSectionDescriptor (_XLFormDescriptor) -@property NSArray * allRows; +@property (nonatomic, strong) NSArray * allRows; -(BOOL)evaluateIsHidden; @end @@ -51,11 +51,11 @@ -(BOOL)evaluateIsHidden; @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, readonly, strong) NSMutableArray * allSections; +@property (nonatomic, copy)NSString * title; +@property (nonatomic, readonly) NSMutableDictionary* allRowsByTag; +@property (atomic, strong) NSMutableDictionary* rowObservers; @end @@ -291,7 +291,7 @@ -(NSDictionary *)formValues if (section.multivaluedTag.length > 0){ NSMutableArray * multiValuedValuesArray = [NSMutableArray new]; for (XLFormRowDescriptor * row in section.formRows) { - if (row.value){ + if (row.value && row.value != [NSNull null]){ [multiValuedValuesArray addObject:row.value]; } } @@ -299,8 +299,9 @@ -(NSDictionary *)formValues } else{ for (XLFormRowDescriptor * row in section.formRows) { - if (row.tag.length > 0){ - [result setObject:(row.value ?: [NSNull null]) forKey:row.tag]; + id value = [row.value valueData]; + if (row.tag.length > 0 && value != nil){ + [result setObject:value forKey:row.tag]; } } } diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.h b/XLForm/XL/Descriptors/XLFormRowDescriptor.h index 1e7a4b71..9290c781 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.h @@ -47,18 +47,18 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF @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 (copy, nullable) XLOnChangeBlock onChangeBlock; -@property BOOL useValueFormatterDuringInput; -@property (nullable) NSFormatter *valueFormatter; +@property (nonatomic, nullable, strong) id cellClass; +@property (nonatomic, readwrite, nullable, copy) NSString * tag; +@property (nonatomic, readonly, nonnull, copy) NSString * rowType; +@property (nonatomic, nullable, copy) NSString * title; +@property (nonatomic, nullable, strong) id value; +@property (nonatomic, nullable) Class valueTransformer; +@property (nonatomic, assign) UITableViewCellStyle cellStyle; +@property (nonatomic, assign) CGFloat height; + +@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,20 +66,20 @@ 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 * cellConfigForSelector; -@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 (getter=isRequired, nonatomic, assign) BOOL required; -@property (nonnull) XLFormAction * action; +@property (nonatomic, nonnull, strong) XLFormAction * action; -@property (weak, null_unspecified) XLFormSectionDescriptor * sectionDescriptor; +@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; @@ -87,7 +87,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)validator; -(void)removeValidator:(nonnull id)validator; -(nullable XLFormValidationStatus *)doValidation; @@ -95,9 +95,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; @@ -126,13 +126,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 @@ -155,15 +155,15 @@ 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, copy) NSString * viewControllerStoryboardId; +@property (nullable, nonatomic, copy) NSString * viewControllerNibName; @property (nonatomic) 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, copy) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead"); +@property (nullable, nonatomic, copy) NSString * formSegueIdentifier; @property (nullable, nonatomic, strong) Class formSegueClass; @end diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index bfe90e60..689570b0 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -33,7 +33,7 @@ @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; @@ -51,13 +51,13 @@ -(void)hideFormRow:(XLFormRowDescriptor*)formRow; @interface XLFormRowDescriptor() -@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 diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.h b/XLForm/XL/Descriptors/XLFormSectionDescriptor.h index f0553fdb..361cf81d 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.h @@ -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) 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; diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index 88aa4d6f..bc097a37 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -32,7 +32,7 @@ @interface XLFormDescriptor (_XLFormSectionDescriptor) -@property (readonly) NSDictionary* allRowsByTag; +@property (nonatomic, readonly) NSDictionary* allRowsByTag; -(void)addRowToTagCollection:(XLFormRowDescriptor*)rowDescriptor; -(void)removeRowFromTagCollection:(XLFormRowDescriptor*) rowDescriptor; @@ -46,10 +46,10 @@ -(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)p @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 diff --git a/XLForm/XL/Helpers/Views/XLFormTextView.h b/XLForm/XL/Helpers/Views/XLFormTextView.h index f157ca67..546239d4 100644 --- a/XLForm/XL/Helpers/Views/XLFormTextView.h +++ b/XLForm/XL/Helpers/Views/XLFormTextView.h @@ -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 diff --git a/XLForm/XL/Helpers/Views/XLFormTextView.m b/XLForm/XL/Helpers/Views/XLFormTextView.m index b95ab991..c71deeee 100644 --- a/XLForm/XL/Helpers/Views/XLFormTextView.m +++ b/XLForm/XL/Helpers/Views/XLFormTextView.m @@ -67,14 +67,15 @@ - (void)drawRect:(CGRect)rect { 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; diff --git a/XLForm/XL/Validation/XLFormRegexValidator.h b/XLForm/XL/Validation/XLFormRegexValidator.h index f2cc95b8..a20bf085 100644 --- a/XLForm/XL/Validation/XLFormRegexValidator.h +++ b/XLForm/XL/Validation/XLFormRegexValidator.h @@ -29,8 +29,8 @@ @interface XLFormRegexValidator : XLFormValidator -@property NSString *msg; -@property NSString *regex; +@property (nonatomic, copy) NSString *msg; +@property (nonatomic, copy) NSString *regex; - (instancetype)initWithMsg:(NSString*)msg andRegexString:(NSString*)regex; + (XLFormRegexValidator *)formRegexValidatorWithMsg:(NSString *)msg regex:(NSString *)regex; diff --git a/XLForm/XL/Validation/XLFormValidationStatus.h b/XLForm/XL/Validation/XLFormValidationStatus.h index 78fd8273..0dc4cc3d 100644 --- a/XLForm/XL/Validation/XLFormValidationStatus.h +++ b/XLForm/XL/Validation/XLFormValidationStatus.h @@ -29,8 +29,8 @@ @interface XLFormValidationStatus : NSObject -@property NSString *msg; -@property BOOL isValid; +@property (nonatomic, copy) NSString *msg; +@property (nonatomic, assign) BOOL isValid; @property (nonatomic, weak) XLFormRowDescriptor *rowDescriptor; //-(instancetype)initWithMsg:(NSString*)msg andStatus:(BOOL)isValid; From 8c03c7b3583179145aa60f14ef0b6f834332b349 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 17 Dec 2018 13:10:05 +0200 Subject: [PATCH 09/27] fixed memory leaks [2] --- Examples/Objective-C/Podfile | 2 + Examples/Objective-C/Podfile.lock | 10 ++- XLForm.podspec | 2 +- XLForm/XL/Cell/XLFormDatePickerCell.m | 17 ++--- XLForm/XL/Descriptors/XLFormDescriptor.h | 2 +- XLForm/XL/Descriptors/XLFormRowDescriptor.h | 6 +- .../XL/Descriptors/XLFormSectionDescriptor.h | 2 +- .../XL/Descriptors/XLFormSectionDescriptor.m | 2 +- .../Views/XLFormRowNavigationAccessoryView.h | 6 +- .../Views/XLFormRowNavigationAccessoryView.m | 69 +++++-------------- 10 files changed, 45 insertions(+), 73 deletions(-) diff --git a/Examples/Objective-C/Podfile b/Examples/Objective-C/Podfile index 01e05543..6374eb45 100644 --- a/Examples/Objective-C/Podfile +++ b/Examples/Objective-C/Podfile @@ -11,4 +11,6 @@ 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' +#DEBUG +pod 'MLeaksFinder' end diff --git a/Examples/Objective-C/Podfile.lock b/Examples/Objective-C/Podfile.lock index 61d25068..ff646f46 100644 --- a/Examples/Objective-C/Podfile.lock +++ b/Examples/Objective-C/Podfile.lock @@ -21,7 +21,10 @@ PODS: - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - AXRatingView (1.0.3) + - FBRetainCycleDetector (0.1.4) - JVFloatLabeledTextField (1.0.2) + - MLeaksFinder (1.0.0): + - FBRetainCycleDetector - SHSPhoneComponent (2.15) - XLData (2.0.0): - XLData/Core (= 2.0.0) @@ -49,6 +52,7 @@ DEPENDENCIES: - AFNetworking (~> 2.0) - AXRatingView (= 1.0.3) - JVFloatLabeledTextField (= 1.0.2) + - MLeaksFinder - SHSPhoneComponent - XLData (from `https://github.com/xmartlabs/XLData.git`, commit `1f9019b56242a2019c7f7e11ec4ef823c397ebcf`) - XLForm (from `../../`) @@ -57,7 +61,9 @@ SPEC REPOS: https://github.com/cocoapods/specs.git: - AFNetworking - AXRatingView + - FBRetainCycleDetector - JVFloatLabeledTextField + - MLeaksFinder - SHSPhoneComponent EXTERNAL SOURCES: @@ -75,11 +81,13 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 AXRatingView: ccaadc1bbda99a4b7e1d556059482d2b933a9f4e + FBRetainCycleDetector: 46f8179bbb1c587deee3ea838a1a3ee02acf5015 JVFloatLabeledTextField: 58a3a32cfb800e5b224f676987e7c13abf50a14d + MLeaksFinder: 8c435bd2f6d070af18cff082b503b21adc130fc0 SHSPhoneComponent: 4cec0653a150ad63cbc52b0c8b29ce2d3c9c26f0 XLData: df725c6179e2e0c80bf56a1ecad9afd169707a6d XLForm: c173e0476a302add7753520d4ab4f18f3eb47ea3 -PODFILE CHECKSUM: 64fbcd03a2c13762b2c18e3938cc8008807937c9 +PODFILE CHECKSUM: 0d959d120f072872333fd8e1a3081196be087a32 COCOAPODS: 1.5.3 diff --git a/XLForm.podspec b/XLForm.podspec index 9acf914a..72e5158f 100644 --- a/XLForm.podspec +++ b/XLForm.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'XLForm' - s.version = '4.0.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 diff --git a/XLForm/XL/Cell/XLFormDatePickerCell.m b/XLForm/XL/Cell/XLFormDatePickerCell.m index 9f9f7aa1..bc277509 100644 --- a/XLForm/XL/Cell/XLFormDatePickerCell.m +++ b/XLForm/XL/Cell/XLFormDatePickerCell.m @@ -37,16 +37,6 @@ -(BOOL)canResignFirstResponder 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)datePickerValueChanged:(UIDatePicker *)sender -(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}]]; } diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.h b/XLForm/XL/Descriptors/XLFormDescriptor.h index b02ef2e8..5d6a12e7 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormDescriptor.h @@ -49,7 +49,7 @@ typedef NS_OPTIONS(NSUInteger, XLFormRowNavigationOptions) { @interface XLFormDescriptor : NSObject -@property (nonatomic, readonly, nonnull) NSMutableArray * formSections; +@property (nonatomic, strong, readonly, nonnull) NSMutableArray * formSections; @property (nonatomic, readonly, nullable, copy) NSString * title; @property (nonatomic, assign) BOOL endEditingTableViewOnScroll; @property (nonatomic, assign) BOOL assignFirstResponderOnShow; diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.h b/XLForm/XL/Descriptors/XLFormRowDescriptor.h index 9290c781..d585d754 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.h @@ -154,16 +154,16 @@ typedef NS_ENUM(NSUInteger, XLFormLeftRightSelectorOptionLeftValueChangePolicy) @interface XLFormAction : NSObject -@property (nullable, nonatomic, strong) Class viewControllerClass; +@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, copy) void (^formBlock)(XLFormRowDescriptor * __nonnull sender); @property (nullable, nonatomic) SEL formSelector; @property (nullable, nonatomic, copy) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead"); @property (nullable, nonatomic, copy) NSString * formSegueIdentifier; -@property (nullable, nonatomic, strong) Class formSegueClass; +@property (nullable, nonatomic) Class formSegueClass; @end diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.h b/XLForm/XL/Descriptors/XLFormSectionDescriptor.h index 361cf81d..f65c0844 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.h @@ -44,7 +44,7 @@ typedef NS_ENUM(NSUInteger, XLFormSectionInsertMode) { @property (nonatomic, nullable, copy) NSString * title; @property (nonatomic, nullable, copy) NSString * footerTitle; -@property (nonatomic, readonly, nonnull) NSMutableArray * formRows; +@property (nonatomic, readonly, nonnull, strong) NSMutableArray * formRows; @property (nonatomic, readonly, assign) XLFormSectionInsertMode sectionInsertMode; @property (nonatomic, readonly, assign) XLFormSectionOptions sectionOptions; diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index bc097a37..22436b42 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -32,7 +32,7 @@ @interface XLFormDescriptor (_XLFormSectionDescriptor) -@property (nonatomic, readonly) NSDictionary* allRowsByTag; +@property (nonatomic, readonly, strong) NSDictionary* allRowsByTag; -(void)addRowToTagCollection:(XLFormRowDescriptor*)rowDescriptor; -(void)removeRowFromTagCollection:(XLFormRowDescriptor*) rowDescriptor; diff --git a/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.h b/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.h index 8e5c708d..54a076e0 100755 --- a/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.h +++ b/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.h @@ -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 diff --git a/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.m b/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.m index f769a5ba..46ceeb76 100755 --- a/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.m +++ b/XLForm/XL/Helpers/Views/XLFormRowNavigationAccessoryView.m @@ -25,14 +25,6 @@ #import "XLFormRowNavigationAccessoryView.h" - -@interface XLFormRowNavigationAccessoryView () - -@property (nonatomic) UIBarButtonItem *fixedSpace; -@property (nonatomic) UIBarButtonItem *flexibleSpace; - -@end - @implementation XLFormRowNavigationAccessoryView @synthesize previousButton = _previousButton; @@ -44,55 +36,30 @@ - (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 From c8fc3759bb8c6dbd23d08448b65123ce6a532ded Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Tue, 18 Dec 2018 12:09:50 +0200 Subject: [PATCH 10/27] updated logic --- XLForm/XL/Cell/XLFormInlineSelectorCell.m | 2 +- XLForm/XL/Cell/XLFormTextFieldCell.m | 4 ++ XLForm/XL/Controllers/XLFormViewController.m | 4 ++ XLForm/XL/Helpers/UIView+XLFormAdditions.h | 2 +- XLForm/XL/Helpers/UIView+XLFormAdditions.m | 45 +++++++++++++------- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/XLForm/XL/Cell/XLFormInlineSelectorCell.m b/XLForm/XL/Cell/XLFormInlineSelectorCell.m index c2cb15e9..77a621c8 100644 --- a/XLForm/XL/Cell/XLFormInlineSelectorCell.m +++ b/XLForm/XL/Cell/XLFormInlineSelectorCell.m @@ -43,7 +43,7 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { BOOL result = [super becomeFirstResponder]; - if (self.isFirstResponder){ + if (!self.isFirstResponder){ return result; } _beforeChangeColor = self.detailTextLabel.textColor; diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index 46ba126e..bfb919da 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -69,6 +69,10 @@ -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStri -(void)dealloc { + [self.contentView removeConstraints:self.dynamicCustomConstraints]; + + self.dynamicCustomConstraints = nil; + [self.textLabel removeObserver:self forKeyPath:@"text"]; [self.imageView removeObserver:self forKeyPath:@"image"]; } diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 6f41ff5d..654e0f33 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -107,6 +107,10 @@ - (void)dealloc { self.tableView.delegate = nil; self.tableView.dataSource = nil; + + self.form.delegate = nil; + + self.navigationAccessoryView = nil; } - (void)viewDidLoad diff --git a/XLForm/XL/Helpers/UIView+XLFormAdditions.h b/XLForm/XL/Helpers/UIView+XLFormAdditions.h index 406f7dd2..34c1cef6 100644 --- a/XLForm/XL/Helpers/UIView+XLFormAdditions.h +++ b/XLForm/XL/Helpers/UIView+XLFormAdditions.h @@ -28,7 +28,7 @@ @interface UIView (XLFormAdditions) -+(id)autolayoutView; ++(instancetype)autolayoutView; -(NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view; -(UIView *)findFirstResponder; -(UITableViewCell *)formDescriptorCell; diff --git a/XLForm/XL/Helpers/UIView+XLFormAdditions.m b/XLForm/XL/Helpers/UIView+XLFormAdditions.m index 3113265d..c4bbbf18 100644 --- a/XLForm/XL/Helpers/UIView+XLFormAdditions.m +++ b/XLForm/XL/Helpers/UIView+XLFormAdditions.m @@ -27,47 +27,60 @@ @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; + UIView *fr = [subView findFirstResponder]; + if (fr != nil) { + firstResponder = fr; + + break; } } - return nil; + + return firstResponder; } - (UITableViewCell *)formDescriptorCell { + UITableViewCell * tableViewCell = nil; + if ([self isKindOfClass:[UITableViewCell class]]) { if ([self conformsToProtocol:@protocol(XLFormDescriptorCell)]){ - return (UITableViewCell *)self; + tableViewCell = (UITableViewCell *)self; } - return nil; } - if (self.superview) { - UITableViewCell * tableViewCell = [self.superview formDescriptorCell]; - if (tableViewCell != nil) { - return tableViewCell; + else if (self.superview) { + UITableViewCell * cell = [self.superview formDescriptorCell]; + if (cell != nil) { + tableViewCell = cell; } } - return nil; + + return tableViewCell; } @end From 1f876ee12b1f4d7c9b8d9ef47a01f847893f96b9 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Tue, 18 Dec 2018 15:36:50 +0200 Subject: [PATCH 11/27] fixed memory leaks --- XLForm/XL/Cell/XLFormSegmentedCell.m | 3 +++ XLForm/XL/Cell/XLFormTextFieldCell.m | 3 +-- XLForm/XL/Descriptors/XLFormDescriptor.m | 9 +++++++++ XLForm/XL/Descriptors/XLFormRowDescriptor.m | 3 +++ XLForm/XL/Descriptors/XLFormSectionDescriptor.m | 6 ++++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/XLForm/XL/Cell/XLFormSegmentedCell.m b/XLForm/XL/Cell/XLFormSegmentedCell.m index d33db2ea..f98fe356 100644 --- a/XLForm/XL/Cell/XLFormSegmentedCell.m +++ b/XLForm/XL/Cell/XLFormSegmentedCell.m @@ -168,6 +168,9 @@ -(void)updateConstraints -(void)dealloc { [self.textLabel removeObserver:self forKeyPath:@"text"]; + + [self.dynamicCustomConstraints removeAllObjects]; + self.dynamicCustomConstraints = nil; } @end diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index bfb919da..a6b9ae9b 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -69,8 +69,7 @@ -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStri -(void)dealloc { - [self.contentView removeConstraints:self.dynamicCustomConstraints]; - + [self.dynamicCustomConstraints removeAllObjects]; self.dynamicCustomConstraints = nil; [self.textLabel removeObserver:self forKeyPath:@"text"]; diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.m b/XLForm/XL/Descriptors/XLFormDescriptor.m index 09279848..c425b159 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormDescriptor.m @@ -406,6 +406,15 @@ -(void)dealloc [self removeObserver:self forKeyPath:@"formSections"]; } @catch (NSException * __unused exception) {} + + [_formSections removeAllObjects]; + _formSections = nil; + [_allSections removeAllObjects]; + _allSections = nil; + [_allRowsByTag removeAllObjects]; + _allRowsByTag = nil; + [_rowObservers removeAllObjects]; + _rowObservers = nil; } #pragma mark - KVC diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index 689570b0..3e8e19cb 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -306,6 +306,9 @@ -(void)dealloc [self removeObserver:self forKeyPath:@"hidePredicateCache"]; } @catch (NSException * __unused exception) {} + + [self.validators removeAllObjects]; + self.validators = nil; } #pragma mark - KVO diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index 22436b42..0df5da7b 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -204,6 +204,12 @@ -(void)dealloc [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 From b65639beff01df311fff64d53791c0d14e652887 Mon Sep 17 00:00:00 2001 From: liraz Date: Sun, 10 Feb 2019 16:36:41 -0600 Subject: [PATCH 12/27] fix for crash #1043 --- XLForm/XL/Cell/XLFormTextFieldCell.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index a6b9ae9b..f85b6bc3 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -69,6 +69,9 @@ -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStri -(void)dealloc { + [self.textField removeTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; + self.textField.delegate = nil; + [self.dynamicCustomConstraints removeAllObjects]; self.dynamicCustomConstraints = nil; From 2bff51d2f8944dee27f6362660be4c69dde73d2f Mon Sep 17 00:00:00 2001 From: liraz Date: Sun, 10 Feb 2019 21:24:29 -0600 Subject: [PATCH 13/27] fix for crash #1044 --- XLForm/XL/Controllers/XLFormViewController.m | 23 +++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 654e0f33..3ed72060 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -105,6 +105,11 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder - (void)dealloc { + 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]; + self.tableView.delegate = nil; self.tableView.dataSource = nil; @@ -575,18 +580,24 @@ -(void)reloadFormRow:(XLFormRowDescriptor *)formRow -(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]; From 34e0d9f199ad919b948da271bad012720c3b87c8 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 11 Feb 2019 12:33:48 +0700 Subject: [PATCH 14/27] fix for issue #1044 --- XLForm/XL/Controllers/XLFormViewController.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 3ed72060..3558d11d 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -105,11 +105,6 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder - (void)dealloc { - 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]; - self.tableView.delegate = nil; self.tableView.dataSource = nil; From f00172cbda54d6d1df5236e955830bcf9e23f2f5 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 11 Feb 2019 13:37:00 +0700 Subject: [PATCH 15/27] fix for issue #1044 --- XLForm/XL/Controllers/XLFormViewController.m | 48 ++++++++------------ 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 3558d11d..35d6c991 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -105,6 +105,11 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder - (void)dealloc { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self name:UIContentSizeCate goryDidChangeNotification object:nil]; + [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil]; + [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil]; + self.tableView.delegate = nil; self.tableView.dataSource = nil; @@ -147,6 +152,21 @@ - (void)viewDidLoad self.tableView.allowsSelectionDuringEditing = YES; self.form.delegate = self; _oldBottomTableContentInset = nil; + + 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)viewWillAppear:(BOOL)animated @@ -160,34 +180,6 @@ -(void)viewWillAppear:(BOOL)animated [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]; - -} - --(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 From 4ab654b51282646ad8878181cd8613f6b5080c8a Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 11 Feb 2019 13:51:29 +0700 Subject: [PATCH 16/27] fixed mistake --- XLForm/XL/Controllers/XLFormViewController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 35d6c991..36b9662b 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -106,7 +106,7 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder - (void)dealloc { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc removeObserver:self name:UIContentSizeCate goryDidChangeNotification object:nil]; + [nc removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil]; [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil]; From 71aaba4ec2ea286e748c6644f866f14719f64c3f Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 11 Feb 2019 15:11:09 +0700 Subject: [PATCH 17/27] fixed observation if lib uses in drawer controller --- XLForm/XL/Controllers/XLFormViewController.m | 63 +++++++++++++------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index 36b9662b..beb88d2c 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -58,6 +58,7 @@ @interface XLFormViewController() } @property (nonatomic, assign) UITableViewStyle tableViewStyle; @property (nonatomic, strong) XLFormRowNavigationAccessoryView * navigationAccessoryView; +@property (atomic , assign) BOOL isObserversAdded; @end @@ -105,10 +106,7 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder - (void)dealloc { - 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]; + [self removeObserverFroController]; self.tableView.delegate = nil; self.tableView.dataSource = nil; @@ -152,34 +150,22 @@ - (void)viewDidLoad self.tableView.allowsSelectionDuringEditing = YES; self.form.delegate = self; _oldBottomTableContentInset = nil; - - 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]; - + _isObserversAdded = NO; } -(void)viewWillAppear:(BOOL)animated { [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]; } + + [self addObserverToController]; } - (void)viewDidAppear:(BOOL)animated @@ -191,11 +177,48 @@ - (void)viewDidAppear:(BOOL)animated } } +-(void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + + [self removeObserverFroController]; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } +- (void)addObserverToController { + if (!self.isObserversAdded) { + _isObserversAdded = YES; + + 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)removeObserverFroController { + if (self.isObserversAdded) { + _isObserversAdded = NO; + + 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 From af64a9ad145823ac108580fb19ce5a6be478c69d Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Mon, 11 Feb 2019 18:52:52 +0700 Subject: [PATCH 18/27] fixed kvo crash --- XLForm/XL/Cell/XLFormTextFieldCell.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/XLForm/XL/Cell/XLFormTextFieldCell.m b/XLForm/XL/Cell/XLFormTextFieldCell.m index f85b6bc3..7683328e 100644 --- a/XLForm/XL/Cell/XLFormTextFieldCell.m +++ b/XLForm/XL/Cell/XLFormTextFieldCell.m @@ -70,13 +70,13 @@ -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStri -(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; - - [self.textLabel removeObserver:self forKeyPath:@"text"]; - [self.imageView removeObserver:self forKeyPath:@"image"]; } #pragma mark - XLFormDescriptorCell From 5c3c50f6dbe6a675f2f4dc2b1183b26e56812d9e Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Tue, 12 Feb 2019 19:09:11 +0700 Subject: [PATCH 19/27] reverted last fix --- XLForm/XL/Controllers/XLFormViewController.m | 60 ++++++++------------ 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index beb88d2c..ed6aae23 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -58,7 +58,6 @@ @interface XLFormViewController() } @property (nonatomic, assign) UITableViewStyle tableViewStyle; @property (nonatomic, strong) XLFormRowNavigationAccessoryView * navigationAccessoryView; -@property (atomic , assign) BOOL isObserversAdded; @end @@ -104,10 +103,8 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder return self; } -- (void)dealloc +-(void)dealloc { - [self removeObserverFroController]; - self.tableView.delegate = nil; self.tableView.dataSource = nil; @@ -116,7 +113,7 @@ - (void)dealloc self.navigationAccessoryView = nil; } -- (void)viewDidLoad +-(void)viewDidLoad { [super viewDidLoad]; @@ -150,7 +147,6 @@ - (void)viewDidLoad self.tableView.allowsSelectionDuringEditing = YES; self.form.delegate = self; _oldBottomTableContentInset = nil; - _isObserversAdded = NO; } -(void)viewWillAppear:(BOOL)animated @@ -168,7 +164,7 @@ -(void)viewWillAppear:(BOOL)animated [self addObserverToController]; } -- (void)viewDidAppear:(BOOL)animated +-(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (self.form.assignFirstResponderOnShow) { @@ -189,35 +185,27 @@ - (void)didReceiveMemoryWarning [super didReceiveMemoryWarning]; } -- (void)addObserverToController { - if (!self.isObserversAdded) { - _isObserversAdded = YES; - - 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)removeObserverFroController { - if (self.isObserversAdded) { - _isObserversAdded = NO; - - 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]; - } +-(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)removeObserverFroController { + 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 From 67bcf798b64eb563ed35987799862dabfc3052be Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 13 Feb 2019 13:44:43 +0700 Subject: [PATCH 20/27] cleanup --- .../Inline Segmented/XLFormInlineSegmentedCell.m | 5 ++--- Examples/Objective-C/Podfile | 2 -- XLForm/XL/Cell/XLFormDateCell.m | 7 ++++--- XLForm/XL/Cell/XLFormInlineSelectorCell.m | 6 +++--- XLForm/XL/Cell/XLFormSelectorCell.m | 4 ++-- XLForm/XL/Controllers/XLFormOptionsObject.m | 2 +- XLForm/XL/Controllers/XLFormViewController.m | 4 ++-- 7 files changed, 14 insertions(+), 16 deletions(-) diff --git a/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m b/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m index 1b7b30c9..767d7adc 100644 --- a/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m +++ b/Examples/Objective-C/Inline Segmented/XLFormInlineSegmentedCell.m @@ -26,11 +26,10 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { - BOOL result = [super becomeFirstResponder]; if (self.isFirstResponder){ - return result; + return [super becomeFirstResponder]; } - + BOOL result = [super becomeFirstResponder]; if (result){ XLFormRowDescriptor * inlineRowDescriptor = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:[XLFormViewController inlineRowDescriptorTypesForRowDescriptorTypes][self.rowDescriptor.rowType]]; UITableViewCell * cell = [inlineRowDescriptor cellForFormController:self.formViewController]; diff --git a/Examples/Objective-C/Podfile b/Examples/Objective-C/Podfile index 6374eb45..01e05543 100644 --- a/Examples/Objective-C/Podfile +++ b/Examples/Objective-C/Podfile @@ -11,6 +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' -#DEBUG -pod 'MLeaksFinder' end diff --git a/XLForm/XL/Cell/XLFormDateCell.m b/XLForm/XL/Cell/XLFormDateCell.m index beae02bb..5821fcd7 100644 --- a/XLForm/XL/Cell/XLFormDateCell.m +++ b/XLForm/XL/Cell/XLFormDateCell.m @@ -60,11 +60,11 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { - BOOL result = [super becomeFirstResponder]; if (self.isFirstResponder){ - return result; + return [super becomeFirstResponder]; } _beforeChangeColor = self.detailTextLabel.textColor; + BOOL result = [super becomeFirstResponder]; if (result){ if ([self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeTimeInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeDateTimeInline] || [self.rowDescriptor.rowType isEqualToString:XLFormRowDescriptorTypeCountDownTimerInline]) { @@ -95,10 +95,11 @@ -(BOOL)resignFirstResponder NSIndexPath * selectedRowPath = [self.formViewController.form indexPathOfFormRow:self.rowDescriptor]; NSIndexPath * nextRowPath = [NSIndexPath indexPathForRow:selectedRowPath.row + 1 inSection:selectedRowPath.section]; XLFormRowDescriptor * nextFormRow = [self.formViewController.form formRowAtIndex:nextRowPath]; + BOOL result = [super resignFirstResponder]; if ([nextFormRow.rowType isEqualToString:XLFormRowDescriptorTypeDatePicker]){ [self.rowDescriptor.sectionDescriptor removeFormRow:nextFormRow]; } - return [super resignFirstResponder]; + return result; } return [super resignFirstResponder]; } diff --git a/XLForm/XL/Cell/XLFormInlineSelectorCell.m b/XLForm/XL/Cell/XLFormInlineSelectorCell.m index 77a621c8..48b96836 100644 --- a/XLForm/XL/Cell/XLFormInlineSelectorCell.m +++ b/XLForm/XL/Cell/XLFormInlineSelectorCell.m @@ -42,11 +42,11 @@ - (BOOL)canBecomeFirstResponder -(BOOL)becomeFirstResponder { - BOOL result = [super becomeFirstResponder]; - if (!self.isFirstResponder){ - return result; + if (self.isFirstResponder){ + return [super becomeFirstResponder]; } _beforeChangeColor = self.detailTextLabel.textColor; + BOOL result = [super becomeFirstResponder]; if (result){ XLFormRowDescriptor * inlineRowDescriptor = [XLFormRowDescriptor formRowDescriptorWithTag:nil rowType:[XLFormViewController inlineRowDescriptorTypesForRowDescriptorTypes][self.rowDescriptor.rowType]]; UITableViewCell * cell = [inlineRowDescriptor cellForFormController:self.formViewController]; diff --git a/XLForm/XL/Cell/XLFormSelectorCell.m b/XLForm/XL/Cell/XLFormSelectorCell.m index 5b51f504..956abeaa 100644 --- a/XLForm/XL/Cell/XLFormSelectorCell.m +++ b/XLForm/XL/Cell/XLFormSelectorCell.m @@ -58,7 +58,7 @@ -(NSString *)valueDisplayText } NSMutableArray * descriptionArray = [NSMutableArray arrayWithCapacity:[self.rowDescriptor.value count]]; //add by OE Ex: value taken form the lacal cache but selectorOptions in the networking - if (self.rowDescriptor.selectorOptions.count>0){ + if (self.rowDescriptor.selectorOptions.count > 0) { for (id option in self.rowDescriptor.selectorOptions) { NSArray * selectedValues = self.rowDescriptor.value; @@ -76,7 +76,7 @@ -(NSString *)valueDisplayText } } } - }else{ + } else { for (id option in self.rowDescriptor.value) { if ([option isKindOfClass:[XLFormOptionsObject class]]) { XLFormOptionsObject *newOption = (XLFormOptionsObject*)option; diff --git a/XLForm/XL/Controllers/XLFormOptionsObject.m b/XLForm/XL/Controllers/XLFormOptionsObject.m index a029ef1d..7ff7f393 100644 --- a/XLForm/XL/Controllers/XLFormOptionsObject.m +++ b/XLForm/XL/Controllers/XLFormOptionsObject.m @@ -29,7 +29,7 @@ @implementation XLFormOptionsObject +(XLFormOptionsObject *)formOptionsObjectWithValue:(id)value displayText:(NSString *)displayText { - return [[self alloc] initWithValue:value displayText:displayText]; + return [[XLFormOptionsObject alloc] initWithValue:value displayText:displayText]; } -(instancetype)initWithValue:(id)value displayText:(NSString *)displayText diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index ed6aae23..e6801011 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -177,7 +177,7 @@ -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; - [self removeObserverFroController]; + [self removeObserverFromController]; } - (void)didReceiveMemoryWarning @@ -201,7 +201,7 @@ -(void)addObserverToController { object:nil]; } --(void)removeObserverFroController { +-(void)removeObserverFromController { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil]; [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil]; From 452f148204a3aa26aecb73ec5ba6bad740679694 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Wed, 13 Feb 2019 18:06:32 +0700 Subject: [PATCH 21/27] fixed kvo --- XLForm/XL/Helpers/Views/XLFormTextView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XLForm/XL/Helpers/Views/XLFormTextView.m b/XLForm/XL/Helpers/Views/XLFormTextView.m index c71deeee..332bc317 100644 --- a/XLForm/XL/Helpers/Views/XLFormTextView.m +++ b/XLForm/XL/Helpers/Views/XLFormTextView.m @@ -30,7 +30,7 @@ @implementation XLFormTextView - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil]; } - (instancetype)initWithFrame:(CGRect)frame From ce169a85705c2abe219f0b60fef245eefd56b78c Mon Sep 17 00:00:00 2001 From: liraz Date: Wed, 13 Feb 2019 17:07:45 -0600 Subject: [PATCH 22/27] fix for crash #1043 --- XLForm/XL/Controllers/XLFormViewController.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/XLForm/XL/Controllers/XLFormViewController.m b/XLForm/XL/Controllers/XLFormViewController.m index e6801011..d112476e 100755 --- a/XLForm/XL/Controllers/XLFormViewController.m +++ b/XLForm/XL/Controllers/XLFormViewController.m @@ -105,6 +105,8 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder -(void)dealloc { + [self removeObserverFromController]; + self.tableView.delegate = nil; self.tableView.dataSource = nil; From 9ead0bb1c50d6425c58a6fe98eaa70bb3e4e30c1 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Thu, 14 Feb 2019 14:50:58 +0700 Subject: [PATCH 23/27] reverted https://github.com/xmartlabs/XLForm/pull/1045#discussion_r255965033 --- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ XLForm/XL/Helpers/NSObject+XLFormAdditions.m | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 XLForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/XLForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/XLForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/XLForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/XLForm/XL/Helpers/NSObject+XLFormAdditions.m b/XLForm/XL/Helpers/NSObject+XLFormAdditions.m index f63361c9..13b6214e 100644 --- a/XLForm/XL/Helpers/NSObject+XLFormAdditions.m +++ b/XLForm/XL/Helpers/NSObject+XLFormAdditions.m @@ -53,7 +53,7 @@ -(id)valueData return result; } if ([self conformsToProtocol:@protocol(XLFormOptionObject)]){ - return (id)self; + return [(id)self formValue]; } return nil; } From 4f6de434ebff2c7177bbd646a326f5552c93578a Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Thu, 14 Feb 2019 15:21:33 +0700 Subject: [PATCH 24/27] reverted #948 --- XLForm/XL/Cell/XLFormSelectorCell.m | 36 +++++++++-------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/XLForm/XL/Cell/XLFormSelectorCell.m b/XLForm/XL/Cell/XLFormSelectorCell.m index 956abeaa..b0c9cd90 100644 --- a/XLForm/XL/Cell/XLFormSelectorCell.m +++ b/XLForm/XL/Cell/XLFormSelectorCell.m @@ -57,33 +57,19 @@ -(NSString *)valueDisplayText } } NSMutableArray * descriptionArray = [NSMutableArray arrayWithCapacity:[self.rowDescriptor.value count]]; - //add by OE Ex: value taken form the lacal cache but selectorOptions in the networking - if (self.rowDescriptor.selectorOptions.count > 0) { - - for (id option in self.rowDescriptor.selectorOptions) { - NSArray * selectedValues = self.rowDescriptor.value; - if ([selectedValues formIndexForItem:option] != NSNotFound){ - 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 * tranformedValue = [valueTransformer transformedValue:option]; - if (tranformedValue){ - [descriptionArray addObject:tranformedValue]; - } - } - else{ - [descriptionArray addObject:[option displayText]]; + for (id option in self.rowDescriptor.selectorOptions) { + NSArray * selectedValues = self.rowDescriptor.value; + if ([selectedValues formIndexForItem:option] != NSNotFound){ + 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 * tranformedValue = [valueTransformer transformedValue:option]; + if (tranformedValue){ + [descriptionArray addObject:tranformedValue]; } } - } - } else { - for (id option in self.rowDescriptor.value) { - if ([option isKindOfClass:[XLFormOptionsObject class]]) { - XLFormOptionsObject *newOption = (XLFormOptionsObject*)option; - [descriptionArray addObject:newOption.formDisplayText]; - } - else { - [descriptionArray addObject:[NSString stringWithFormat:@"%@",option]]; + else{ + [descriptionArray addObject:[option displayText]]; } } } From 509ea4dfedfadb8a50db59e24b109185de70f415 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Fri, 15 Feb 2019 16:48:48 +0700 Subject: [PATCH 25/27] fixed firstResponder logic --- XLForm/XL/Helpers/UIView+XLFormAdditions.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/XLForm/XL/Helpers/UIView+XLFormAdditions.m b/XLForm/XL/Helpers/UIView+XLFormAdditions.m index c4bbbf18..c2bc45a6 100644 --- a/XLForm/XL/Helpers/UIView+XLFormAdditions.m +++ b/XLForm/XL/Helpers/UIView+XLFormAdditions.m @@ -52,12 +52,14 @@ - (UIView *)findFirstResponder if (self.isFirstResponder) { firstResponder = self; } - for (UIView *subView in self.subviews) { - UIView *fr = [subView findFirstResponder]; - if (fr != nil) { - firstResponder = fr; - - break; + else { + for (UIView *subView in self.subviews) { + UIView *fr = [subView findFirstResponder]; + if (fr != nil) { + firstResponder = fr; + + break; + } } } From c1a3dabdb8acf9d7b317f80ae5eac0a430027626 Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Thu, 21 Feb 2019 21:27:35 +0700 Subject: [PATCH 26/27] codereview in Descriptors --- .gitignore | 6 +- Examples/Objective-C/Podfile.lock | 16 +- .../XLForm.xcodeproj/project.pbxproj | 4 +- Tests/XLForm Tests.xcodeproj/project.pbxproj | 22 +- XLForm/XL/Descriptors/XLFormDescriptor.m | 343 ++++++++++-------- XLForm/XL/Descriptors/XLFormRowDescriptor.h | 18 +- XLForm/XL/Descriptors/XLFormRowDescriptor.m | 248 +++++++------ .../XL/Descriptors/XLFormSectionDescriptor.m | 142 ++++---- 8 files changed, 440 insertions(+), 359 deletions(-) diff --git a/.gitignore b/.gitignore index b17b9336..7b4b8045 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,5 @@ DerivedData #CocoaPods Pods -Tests/Pods -Tests/Podfile.lock -Examples/Objective-C/Podfile.lock -Examples/Swift/Podfile.lock \ No newline at end of file +Podfile.lock +*.xcworkspace diff --git a/Examples/Objective-C/Podfile.lock b/Examples/Objective-C/Podfile.lock index ff646f46..70445203 100644 --- a/Examples/Objective-C/Podfile.lock +++ b/Examples/Objective-C/Podfile.lock @@ -21,10 +21,7 @@ PODS: - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - AXRatingView (1.0.3) - - FBRetainCycleDetector (0.1.4) - JVFloatLabeledTextField (1.0.2) - - MLeaksFinder (1.0.0): - - FBRetainCycleDetector - SHSPhoneComponent (2.15) - XLData (2.0.0): - XLData/Core (= 2.0.0) @@ -46,13 +43,12 @@ PODS: - XLData/RemoteDataStore (2.0.0): - XLData/CoreRemote - XLData/DataStore - - XLForm (4.0.0) + - XLForm (4.0.1) DEPENDENCIES: - AFNetworking (~> 2.0) - AXRatingView (= 1.0.3) - JVFloatLabeledTextField (= 1.0.2) - - MLeaksFinder - SHSPhoneComponent - XLData (from `https://github.com/xmartlabs/XLData.git`, commit `1f9019b56242a2019c7f7e11ec4ef823c397ebcf`) - XLForm (from `../../`) @@ -61,9 +57,7 @@ SPEC REPOS: https://github.com/cocoapods/specs.git: - AFNetworking - AXRatingView - - FBRetainCycleDetector - JVFloatLabeledTextField - - MLeaksFinder - SHSPhoneComponent EXTERNAL SOURCES: @@ -81,13 +75,11 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 AXRatingView: ccaadc1bbda99a4b7e1d556059482d2b933a9f4e - FBRetainCycleDetector: 46f8179bbb1c587deee3ea838a1a3ee02acf5015 JVFloatLabeledTextField: 58a3a32cfb800e5b224f676987e7c13abf50a14d - MLeaksFinder: 8c435bd2f6d070af18cff082b503b21adc130fc0 SHSPhoneComponent: 4cec0653a150ad63cbc52b0c8b29ce2d3c9c26f0 XLData: df725c6179e2e0c80bf56a1ecad9afd169707a6d - XLForm: c173e0476a302add7753520d4ab4f18f3eb47ea3 + XLForm: b8d47a9a00fb6166981cb40de7169d70d611e9be -PODFILE CHECKSUM: 0d959d120f072872333fd8e1a3081196be087a32 +PODFILE CHECKSUM: 64fbcd03a2c13762b2c18e3938cc8008807937c9 -COCOAPODS: 1.5.3 +COCOAPODS: 1.6.0 diff --git a/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj b/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj index 33a78e9e..b105fa52 100644 --- a/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj +++ b/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj @@ -547,7 +547,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh", "${PODS_ROOT}/../../../XLForm/XLForm.bundle", ); name = "[CP] Copy Pods Resources"; @@ -556,7 +556,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-XLForm/Pods-XLForm-resources.sh\"\n"; showEnvVarsInLog = 0; }; EBE0335CCC7588D83B89A92A /* [CP] Check Pods Manifest.lock */ = { diff --git a/Tests/XLForm Tests.xcodeproj/project.pbxproj b/Tests/XLForm Tests.xcodeproj/project.pbxproj index c8fd9858..d9ee4d88 100644 --- a/Tests/XLForm Tests.xcodeproj/project.pbxproj +++ b/Tests/XLForm Tests.xcodeproj/project.pbxproj @@ -150,7 +150,6 @@ 28657A361990879200CE8180 /* Sources */, 28657A371990879200CE8180 /* Frameworks */, 28657A381990879200CE8180 /* Resources */, - 51F3E228D166F2E8BF8C889E /* [CP] Embed Pods Frameworks */, 7E96395A3A94BDD9487AE471 /* [CP] Copy Pods Resources */, ); buildRules = ( @@ -217,37 +216,22 @@ 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; }; - 51F3E228D166F2E8BF8C889E /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 7E96395A3A94BDD9487AE471 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh", "${PODS_ROOT}/../../XLForm/XLForm.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", + "${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-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-XLForm Tests/Pods-XLForm Tests-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.m b/XLForm/XL/Descriptors/XLFormDescriptor.m index c425b159..a0b8797e 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormDescriptor.m @@ -32,10 +32,13 @@ NSString * const XLFormErrorDomain = @"XLFormErrorDomain"; NSString * const XLValidationStatusErrorKey = @"XLValidationStatusErrorKey"; +NSString * const XLFormSectionsKey = @"formSections"; + @interface XLFormSectionDescriptor (_XLFormDescriptor) -@property (nonatomic, strong) NSArray * allRows; +@property (nonatomic, strong) NSArray *allRows; + -(BOOL)evaluateIsHidden; @end @@ -51,11 +54,11 @@ -(BOOL)evaluateIsHidden; @interface XLFormDescriptor() -@property (nonatomic, strong) NSMutableArray * formSections; -@property (nonatomic, readonly, strong) NSMutableArray * allSections; -@property (nonatomic, copy)NSString * title; -@property (nonatomic, readonly) NSMutableDictionary* allRowsByTag; -@property (atomic, strong) 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 @@ @implementation XLFormDescriptor -(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,8 +81,13 @@ -(instancetype)initWithTitle:(NSString *)title; _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; } @@ -101,11 +108,11 @@ -(void)addFormSection:(XLFormSectionDescriptor *)formSection -(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 @@ -(void)addFormSection:(XLFormSectionDescriptor *)formSection afterSection:(XLFor { 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 @@ -(void)addFormRow:(XLFormRowDescriptor *)formRow beforeRowTag:(NSString *)before [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 @@ -(void)removeFormSectionAtIndex:(NSUInteger)index -(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 @@ -(XLFormRowDescriptor *)formRowWithTag:(NSString *)tag -(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,56 +268,62 @@ -(XLFormSectionDescriptor *)formSectionAtIndex:(NSUInteger)index -(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 && row.value != [NSNull null]){ + 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) { + else { + for (XLFormRowDescriptor *row in section.formRows) { id value = [row.value valueData]; - if (row.tag.length > 0 && value != nil){ + if (row.tag.length > 0 && value != nil) { [result setObject:value forKey:row.tag]; } } } } + return result; } @@ -313,49 +331,55 @@ -(NSDictionary *)httpParameters:(XLFormViewController *)formViewController { 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 *)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]; } } @@ -368,11 +392,11 @@ -(NSArray *)localValidationErrors:(XLFormViewController *)formViewController { - (void)setFirstResponder:(XLFormViewController *)formViewController { - for (XLFormSectionDescriptor * formSection in self.formSections) { - for (XLFormRowDescriptor * row in formSection.formRows) { - UITableViewCell * cell = [row cellForFormController:formViewController]; - if ([cell formDescriptorCellCanBecomeFirstResponder]){ - if ([cell formDescriptorCellBecomeFirstResponder]){ + for (XLFormSectionDescriptor *formSection in self.formSections) { + for (XLFormRowDescriptor *row in formSection.formRows) { + UITableViewCell *cell = [row cellForFormController:formViewController]; + if ([cell formDescriptorCellCanBecomeFirstResponder]) { + if ([cell formDescriptorCellBecomeFirstResponder]) { return; } } @@ -383,18 +407,23 @@ - (void)setFirstResponder:(XLFormViewController *)formViewController #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 *)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]; } } @@ -402,10 +431,7 @@ -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NS -(void)dealloc { - @try { - [self removeObserver:self forKeyPath:@"formSections"]; - } - @catch (NSException * __unused exception) {} + [self removeObserver:self forKeyPath:XLFormSectionsKey]; [_formSections removeAllObjects]; _formSections = nil; @@ -424,19 +450,23 @@ -(NSUInteger)countOfFormSections 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]; } @@ -455,7 +485,8 @@ - (NSArray *)allSectionsAtIndexes:(NSIndexSet *)indexes { 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; @@ -466,7 +497,8 @@ - (void)removeObjectFromAllSectionsAtIndex:(NSUInteger)index { [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; @@ -476,24 +508,23 @@ - (void)insertObject:(XLFormSectionDescriptor *)section inAllSectionsAtIndex:(NS 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]; } } @@ -510,60 +541,65 @@ -(NSMutableArray *)formSections -(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]; } } @@ -571,32 +607,36 @@ -(void)removeRowFromTagCollection:(XLFormRowDescriptor *)rowDescriptor -(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]) @@ -607,31 +647,32 @@ -(void)addObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)pred -(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]; } } diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.h b/XLForm/XL/Descriptors/XLFormRowDescriptor.h index d585d754..088790f6 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.h +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.h @@ -43,20 +43,20 @@ 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 (nonatomic, nullable, strong) id cellClass; -@property (nonatomic, readwrite, nullable, copy) NSString * tag; -@property (nonatomic, readonly, nonnull, copy) NSString * rowType; -@property (nonatomic, nullable, copy) NSString * title; +@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) Class valueTransformer; -@property (nonatomic, assign) UITableViewCellStyle cellStyle; -@property (nonatomic, assign) CGFloat height; +@property (nonatomic, nullable, strong) Class valueTransformer; +@property (nonatomic, assign ) UITableViewCellStyle cellStyle; +@property (nonatomic, assign ) CGFloat height; -@property (nonatomic, copy, nullable) XLOnChangeBlock onChangeBlock; +@property (nonatomic, copy , nullable) XLOnChangeBlock onChangeBlock; @property (nonatomic, assign) BOOL useValueFormatterDuringInput; @property (nonatomic, strong, nullable) NSFormatter *valueFormatter; @@ -73,8 +73,10 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF @property (nonatomic, nonnull, strong) id disabled; -(BOOL)isDisabled; + @property (nonatomic, nonnull, strong) id hidden; -(BOOL)isHidden; + @property (getter=isRequired, nonatomic, assign) BOOL required; @property (nonatomic, nonnull, strong) XLFormAction * action; diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index 3e8e19cb..a575ea04 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -33,7 +33,7 @@ @interface XLFormDescriptor (_XLFormRowDescriptor) -@property (nonatomic, readonly, strong) 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 @@ -(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)p @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() @property (nonatomic, strong) XLFormBaseCell *cell; @property (nonatomic, strong) NSMutableArray *validators; @property (nonatomic, assign) BOOL isDirtyDisablePredicateCache; -@property (nonatomic, copy) NSNumber* disablePredicateCache; +@property (nonatomic, copy ) NSNumber *disablePredicateCache; @property (nonatomic, assign) BOOL isDirtyHidePredicateCache; -@property (nonatomic, copy) NSNumber* hidePredicateCache; +@property (nonatomic, copy ) NSNumber *hidePredicateCache; @end @@ -81,8 +85,7 @@ -(instancetype)init -(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; @@ -99,11 +102,19 @@ -(instancetype)initWithTag:(NSString *)tag rowType:(NSString *)rowType title:(NS _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; } @@ -119,7 +130,7 @@ +(instancetype)formRowDescriptorWithTag:(NSString *)tag rowType:(NSString *)rowT -(XLFormBaseCell *)cellForFormController:(XLFormViewController * __unused)formController { - if (!_cell){ + if (!_cell) { id cellClass = self.cellClass ?: [XLFormViewController cellClassesForRowDescriptorTypes][self.rowType]; NSAssert(cellClass, @"Not defined XLFormRowDescriptorType: %@", self.rowType ?: @""); if ([cellClass isKindOfClass:[NSString class]]) { @@ -132,7 +143,8 @@ -(XLFormBaseCell *)cellForFormController:(XLFormViewController * __unused)formCo NSString *folderName = [components firstObject]; NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:folderName]; bundle = [NSBundle bundleWithPath:bundlePath]; - } else { + } + else { bundle = [NSBundle bundleForClass:NSClassFromString(cellClass)]; cellResource = cellClassString; } @@ -142,85 +154,100 @@ -(XLFormBaseCell *)cellForFormController:(XLFormViewController * __unused)formCo if ([bundle pathForResource:cellResource ofType:@"nib"]){ _cell = [[bundle loadNibNamed:cellResource owner:nil options:nil] firstObject]; } - } else { + } + 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) { - [self->_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) return _cellConfigForSelector; - _cellConfigForSelector = [NSMutableDictionary dictionary]; + 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{ + result = [self displayTextValue]; + } + else { // have formatter, but we don't want to use it during editing - return [self.value displayText]; + result = [self.value displayText]; } - }else{ + } + else { // have value, but no formatter, use the value's displayText - return [self.value displayText]; + result = [self.value displayText]; } - }else{ - // placeholder - return @""; } + + 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 @@ -230,9 +257,10 @@ -(NSString *)description -(XLFormAction *)action { - if (!_action){ + if (!_action) { _action = [[XLFormAction alloc] init]; } + return _action; } @@ -243,13 +271,15 @@ -(void)setAction:(XLFormAction *)action -(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; } @@ -260,52 +290,46 @@ -(void)setHeight:(CGFloat)height { // 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) {} [self.validators removeAllObjects]; self.validators = nil; @@ -315,19 +339,25 @@ -(void)dealloc -(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)]; } } } @@ -337,12 +367,14 @@ -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NS -(BOOL)isDisabled { - if (self.sectionDescriptor.formDescriptor.isDisabled){ + if (self.sectionDescriptor.formDescriptor.isDisabled) { return YES; } + if (self.isDirtyDisablePredicateCache) { [self evaluateIsDisabled]; } + return [self.disablePredicateCache boolValue]; } @@ -351,11 +383,12 @@ -(void)setDisabled:(id)disabled 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]; } @@ -364,7 +397,8 @@ -(BOOL)evaluateIsDisabled 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 ?: @{}]); } @@ -374,12 +408,14 @@ -(BOOL)evaluateIsDisabled }; } } - else{ + else { self.disablePredicateCache = _disabled; } - if ([self.disablePredicateCache boolValue]){ + + if ([self.disablePredicateCache boolValue]) { [self.cell resignFirstResponder]; } + return [self.disablePredicateCache boolValue]; } @@ -423,6 +459,7 @@ -(BOOL)isHidden if (self.isDirtyHidePredicateCache) { return [self evaluateIsHidden]; } + return [self.hidePredicateCache boolValue]; } @@ -431,7 +468,8 @@ -(BOOL)evaluateIsHidden 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 ?: @{}]); } @@ -441,16 +479,18 @@ -(BOOL)evaluateIsHidden }; } } - 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]; } @@ -460,10 +500,12 @@ -(void)setHidden:(id)hidden 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. } @@ -477,34 +519,35 @@ -(id)hidden -(void)addValidator:(id)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)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]) { @@ -512,22 +555,24 @@ -(XLFormValidationStatus *)doValidation 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 v in self.validators) { + for (id v in self.validators) { if ([v conformsToProtocol:@protocol(XLFormValidatorProtocol)]) { XLFormValidationStatus *vStatus = [v isValid:self]; // fail validation @@ -535,10 +580,12 @@ -(XLFormValidationStatus *)doValidation return vStatus; } valStatus = vStatus; - } else { + } + else { valStatus = nil; } } + return valStatus; } @@ -594,13 +641,13 @@ +(XLFormLeftRightSelectorOption *)formLeftRightSelectorOptionWithLeftValue:(id)l -(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; } @@ -611,10 +658,10 @@ @implementation XLFormAction - (instancetype)init { - self = [super init]; - if (self) { + if (self = [super init]) { _viewControllerPresentationMode = XLFormPresentationModeDefault; } + return self; } @@ -626,24 +673,25 @@ -(id)copyWithZone:(NSZone *)zone 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; } @@ -668,7 +716,6 @@ -(void)setViewControllerStoryboardId:(NSString *)viewControllerStoryboardId _viewControllerStoryboardId = viewControllerStoryboardId; } - -(void)setFormSelector:(SEL)formSelector { _formBlock = nil; @@ -677,7 +724,6 @@ -(void)setFormSelector:(SEL)formSelector _formSelector = formSelector; } - -(void)setFormBlock:(void (^)(XLFormRowDescriptor *))formBlock { _formSegueClass = nil; diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index 0df5da7b..21aee63c 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -29,15 +29,16 @@ #import "NSString+XLFormAdditions.h" #import "UIView+XLFormAdditions.h" +NSString * const XLFormRowsKey = @"formRows"; @interface XLFormDescriptor (_XLFormSectionDescriptor) -@property (nonatomic, readonly, strong) NSDictionary* allRowsByTag; +@property (nonatomic, strong, 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 @@ -(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)p @interface XLFormSectionDescriptor() -@property (nonatomic, strong) NSMutableArray * formRows; -@property (nonatomic, strong) NSMutableArray * allRows; +@property (nonatomic, strong) NSMutableArray *formRows; +@property (nonatomic, strong) NSMutableArray *allRows; + @property (nonatomic, assign) BOOL isDirtyHidePredicateCache; -@property (nonatomic, copy) NSNumber* hidePredicateCache; +@property (nonatomic, copy ) NSNumber *hidePredicateCache; @end @@ -60,8 +62,7 @@ @implementation XLFormSectionDescriptor -(instancetype)init { - self = [super init]; - if (self){ + if (self = [super init]) { _formRows = [NSMutableArray array]; _allRows = [NSMutableArray array]; _sectionInsertMode = XLFormSectionInsertModeLastRow; @@ -71,25 +72,35 @@ -(instancetype)init _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,14 +136,12 @@ -(BOOL)isMultivaluedSection -(void)addFormRow:(XLFormRowDescriptor *)formRow { - NSUInteger index; + NSUInteger index = [self.allRows count]; if ([self canInsertUsingButton]) { index = ([self.formRows count] > 0) ? [self.formRows count] - 1 : 0; - } else { - index = [self.allRows count]; } - + [self insertObject:formRow inAllRowsAtIndex:index]; } @@ -144,26 +153,23 @@ -(void)addFormRow:(XLFormRowDescriptor *)formRow afterRow:(XLFormRowDescriptor * } 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]; @@ -174,21 +180,21 @@ -(void)removeFormRowAtIndex:(NSUInteger)index -(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]; @@ -199,11 +205,9 @@ - (void)moveRowAtIndexPath:(NSIndexPath *)sourceIndex toIndexPath:(NSIndexPath * -(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; @@ -220,13 +224,15 @@ -(void)showFormRow:(XLFormRowDescriptor*)formRow{ 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 { @@ -238,36 +244,41 @@ -(void)showFormRow:(XLFormRowDescriptor*)formRow{ -(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 *)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 @@ -350,7 +361,7 @@ -(void)setHidePredicateCache:(NSNumber *)hidePredicateCache { NSParameterAssert(hidePredicateCache != nil); self.isDirtyHidePredicateCache = NO; - if (_hidePredicateCache == nil || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]){ + if (_hidePredicateCache == nil || ![_hidePredicateCache isEqualToNumber:hidePredicateCache]) { _hidePredicateCache = hidePredicateCache; } } @@ -360,6 +371,7 @@ -(BOOL)isHidden if (self.isDirtyHidePredicateCache) { return [self evaluateIsHidden]; } + return [self.hidePredicateCache boolValue]; } @@ -368,7 +380,8 @@ -(BOOL)evaluateIsHidden if ([_hidden isKindOfClass:[NSPredicate class]]) { if (!self.formDescriptor) { self.isDirtyHidePredicateCache = YES; - } else { + } + else { @try { self.hidePredicateCache = @([_hidden evaluateWithObject:self substitutionVariables:self.formDescriptor.allRowsByTag ?: @{}]); } @@ -378,21 +391,24 @@ -(BOOL)evaluateIsHidden }; } } - 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]; } @@ -404,13 +420,15 @@ -(id)hidden -(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. } From d0bc2c56bd18cf3a9e17bdd652c967b71a41864e Mon Sep 17 00:00:00 2001 From: Vitalii Parovishnyk Date: Fri, 22 Feb 2019 18:25:11 +0700 Subject: [PATCH 27/27] codereview --- XLForm/XL/Descriptors/XLFormDescriptor.m | 2 +- XLForm/XL/Descriptors/XLFormRowDescriptor.m | 2 ++ XLForm/XL/Descriptors/XLFormSectionDescriptor.m | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/XLForm/XL/Descriptors/XLFormDescriptor.m b/XLForm/XL/Descriptors/XLFormDescriptor.m index a0b8797e..dc7021ca 100644 --- a/XLForm/XL/Descriptors/XLFormDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormDescriptor.m @@ -37,7 +37,7 @@ @interface XLFormSectionDescriptor (_XLFormDescriptor) -@property (nonatomic, strong) NSArray *allRows; +@property (nonatomic, weak) NSArray *allRows; -(BOOL)evaluateIsHidden; diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m index a575ea04..f071c060 100644 --- a/XLForm/XL/Descriptors/XLFormRowDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.m @@ -331,6 +331,8 @@ -(void)dealloc [self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeDisabled]; [self.sectionDescriptor.formDescriptor removeObserversOfObject:self predicateType:XLPredicateTypeHidden]; + _cell = nil; + [self.validators removeAllObjects]; self.validators = nil; } diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m index 21aee63c..ee8d5cc0 100644 --- a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m +++ b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m @@ -33,7 +33,7 @@ @interface XLFormDescriptor (_XLFormSectionDescriptor) -@property (nonatomic, strong, readonly) NSDictionary *allRowsByTag; +@property (nonatomic, weak, readonly) NSDictionary *allRowsByTag; -(void)addRowToTagCollection:(XLFormRowDescriptor *)rowDescriptor; -(void)removeRowFromTagCollection:(XLFormRowDescriptor *) rowDescriptor;