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/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/Podfile.lock b/Examples/Objective-C/Podfile.lock
index daedd938..70445203 100644
--- a/Examples/Objective-C/Podfile.lock
+++ b/Examples/Objective-C/Podfile.lock
@@ -43,7 +43,7 @@ PODS:
- XLData/RemoteDataStore (2.0.0):
- XLData/CoreRemote
- XLData/DataStore
- - XLForm (4.0.0)
+ - XLForm (4.0.1)
DEPENDENCIES:
- AFNetworking (~> 2.0)
@@ -53,12 +53,19 @@ DEPENDENCIES:
- XLData (from `https://github.com/xmartlabs/XLData.git`, commit `1f9019b56242a2019c7f7e11ec4ef823c397ebcf`)
- XLForm (from `../../`)
+SPEC REPOS:
+ https://github.com/cocoapods/specs.git:
+ - AFNetworking
+ - AXRatingView
+ - JVFloatLabeledTextField
+ - SHSPhoneComponent
+
EXTERNAL SOURCES:
XLData:
:commit: 1f9019b56242a2019c7f7e11ec4ef823c397ebcf
:git: https://github.com/xmartlabs/XLData.git
XLForm:
- :path: ../../
+ :path: "../../"
CHECKOUT OPTIONS:
XLData:
@@ -71,8 +78,8 @@ SPEC CHECKSUMS:
JVFloatLabeledTextField: 58a3a32cfb800e5b224f676987e7c13abf50a14d
SHSPhoneComponent: 4cec0653a150ad63cbc52b0c8b29ce2d3c9c26f0
XLData: df725c6179e2e0c80bf56a1ecad9afd169707a6d
- XLForm: 04110197c12187dd28a6c7295d3d8b95f4fdb4de
+ XLForm: b8d47a9a00fb6166981cb40de7169d70d611e9be
PODFILE CHECKSUM: 64fbcd03a2c13762b2c18e3938cc8008807937c9
-COCOAPODS: 1.3.1
+COCOAPODS: 1.6.0
diff --git a/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj b/Examples/Objective-C/XLForm.xcodeproj/project.pbxproj
index 5113bf54..b105fa52 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,37 +541,22 @@
/* 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;
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";
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/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 */ = {
@@ -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..a76f48d9 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"
},
{
@@ -142,8 +167,15 @@
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
- "role" : "longLook",
- "subtype" : "42mm"
+ "role" : "appLauncher",
+ "subtype" : "40mm"
+ },
+ {
+ "size" : "50x50",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "appLauncher",
+ "subtype" : "44mm"
},
{
"size" : "86x86",
@@ -158,6 +190,30 @@
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
+ },
+ {
+ "size" : "108x108",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "quickLook",
+ "subtype" : "44mm"
+ },
+ {
+ "idiom" : "watch-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "car",
+ "size" : "120x120",
+ "scale" : "1x"
+ },
+ {
+ "size" : "44x44",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "longLook",
+ "subtype" : "42mm"
}
],
"info" : {
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.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.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/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.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/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/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/Cell/XLFormImageCell.m b/XLForm/XL/Cell/XLFormImageCell.m
index 25de18c7..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:alertController animated: true completion: nil];
+ [weak.formViewController presentViewController:self->alertController animated: true completion: nil];
});
}
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..f98fe356 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
@@ -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.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 556493c4..7683328e 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
@@ -69,8 +69,14 @@ -(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;
}
#pragma mark - XLFormDescriptorCell
@@ -79,8 +85,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 +188,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
@@ -225,10 +221,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 +236,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 +275,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.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 b02c14b6..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]];
@@ -160,7 +152,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 +199,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/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 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/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 97180101..d112476e 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
@@ -104,25 +103,34 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder
return self;
}
-- (void)dealloc
+-(void)dealloc
{
+ [self removeObserverFromController];
+
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
+
+ self.form.delegate = nil;
+
+ self.navigationAccessoryView = nil;
}
-- (void)viewDidLoad
+-(void)viewDidLoad
{
[super viewDidLoad];
- if (!self.tableView){
- self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds
+
+ UITableView *tableView = self.tableView;
+ if (!tableView){
+ tableView = [[UITableView alloc] initWithFrame:self.view.bounds
style:self.tableViewStyle];
- self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- if([self.tableView respondsToSelector:@selector(cellLayoutMarginsFollowReadableWidth)]){
- self.tableView.cellLayoutMarginsFollowReadableWidth = NO;
+ tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ if([tableView respondsToSelector:@selector(cellLayoutMarginsFollowReadableWidth)]){
+ tableView.cellLayoutMarginsFollowReadableWidth = NO;
}
}
- if (!self.tableView.superview){
- [self.view addSubview:self.tableView];
+ if (!tableView.superview){
+ [self.view addSubview:tableView];
+ self.tableView = tableView;
}
if (!self.tableView.delegate){
self.tableView.delegate = self;
@@ -147,44 +155,18 @@ -(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];
}
- [[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];
+
+ [self addObserverToController];
}
-- (void)viewDidAppear:(BOOL)animated
+-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.form.assignFirstResponderOnShow) {
@@ -193,11 +175,40 @@ - (void)viewDidAppear:(BOOL)animated
}
}
+-(void)viewDidDisappear:(BOOL)animated
+{
+ [super viewDidDisappear:animated];
+
+ [self removeObserverFromController];
+}
+
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
+-(void)addObserverToController {
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc addObserver:self
+ selector:@selector(contentSizeCategoryChanged:)
+ name:UIContentSizeCategoryDidChangeNotification
+ object:nil];
+ [nc addObserver:self
+ selector:@selector(keyboardWillShow:)
+ name:UIKeyboardWillShowNotification
+ object:nil];
+ [nc addObserver:self
+ selector:@selector(keyboardWillHide:)
+ name:UIKeyboardWillHideNotification
+ object:nil];
+}
+
+-(void)removeObserverFromController {
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
+ [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
+ [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+}
#pragma mark - CellClasses
+(NSMutableDictionary *)cellClassesForRowDescriptorTypes
@@ -314,8 +325,8 @@ -(void)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];
@@ -434,9 +445,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]){
@@ -568,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];
@@ -650,9 +668,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 +686,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 +706,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..5d6a12e7 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, strong, readonly, nonnull) NSMutableArray * formSections;
+@property (nonatomic, readonly, nullable, copy) NSString * title;
+@property (nonatomic, assign) BOOL endEditingTableViewOnScroll;
+@property (nonatomic, assign) BOOL assignFirstResponderOnShow;
+@property (nonatomic, assign) BOOL addAsteriskToRequiredRowsTitle;
+@property (nonatomic, getter=isDisabled, assign) BOOL disabled;
+@property (nonatomic, assign) XLFormRowNavigationOptions rowNavigationOptions;
+
+@property (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 1b6926c7..dc7021ca 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 NSArray * allRows;
+@property (nonatomic, weak) NSArray *allRows;
+
-(BOOL)evaluateIsHidden;
@end
@@ -51,11 +54,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, 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,14 +81,19 @@ -(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;
}
+(instancetype)formDescriptor
{
- return [[self class] formDescriptorWithTitle:nil];
+ return [[self class] formDescriptorWithTitle:@""];
}
+(instancetype)formDescriptorWithTitle:(NSString *)title
@@ -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,55 +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){
+ NSMutableDictionary *result = [NSMutableDictionary dictionary];
+ for (XLFormSectionDescriptor *section in self.formSections) {
+ if (section.multivaluedTag.length > 0) {
+ NSMutableArray *multiValuedValuesArray = [NSMutableArray new];
+ for (XLFormRowDescriptor *row in section.formRows) {
+ if (row.value && row.value != [NSNull null]) {
[multiValuedValuesArray addObject:row.value];
}
}
+
[result setObject:multiValuedValuesArray forKey:section.multivaluedTag];
}
- else{
- for (XLFormRowDescriptor * row in section.formRows) {
- if (row.tag.length > 0){
- [result setObject:(row.value ?: [NSNull null]) forKey:row.tag];
+ else {
+ for (XLFormRowDescriptor *row in section.formRows) {
+ id value = [row.value valueData];
+ if (row.tag.length > 0 && value != nil) {
+ [result setObject:value forKey:row.tag];
}
}
}
}
+
return result;
}
@@ -312,49 +331,55 @@ -(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];
}
}
@@ -367,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;
}
}
@@ -382,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];
}
}
@@ -401,10 +431,16 @@ -(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;
+ [_allSections removeAllObjects];
+ _allSections = nil;
+ [_allRowsByTag removeAllObjects];
+ _allRowsByTag = nil;
+ [_rowObservers removeAllObjects];
+ _rowObservers = nil;
}
#pragma mark - KVC
@@ -414,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];
}
@@ -445,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;
@@ -456,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;
@@ -466,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];
}
}
@@ -500,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];
}
}
@@ -561,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])
@@ -597,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 1e7a4b71..088790f6 100644
--- a/XLForm/XL/Descriptors/XLFormRowDescriptor.h
+++ b/XLForm/XL/Descriptors/XLFormRowDescriptor.h
@@ -43,22 +43,22 @@ typedef NS_ENUM(NSUInteger, XLFormPresentationMode) {
XLFormPresentationModePresent
};
-typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLFormRowDescriptor* __nonnull rowDescriptor);
+typedef void(^XLOnChangeBlock)(id __nullable oldValue, id __nullable newValue, XLFormRowDescriptor * __nonnull rowDescriptor);
@interface XLFormRowDescriptor : NSObject
-@property (nullable) id cellClass;
-@property (readwrite, nullable) NSString * tag;
-@property (readonly, nonnull) NSString * rowType;
-@property (nullable) NSString * title;
-@property (nonatomic, nullable) id value;
-@property (nullable) Class valueTransformer;
-@property UITableViewCellStyle cellStyle;
-@property (nonatomic) CGFloat height;
+@property (nonatomic, nullable, strong) id cellClass;
+@property (nonatomic, nullable, copy , readwrite) NSString * tag;
+@property (nonatomic, nonnull , copy , readonly) NSString * rowType;
+@property (nonatomic, nullable, copy ) NSString * title;
+@property (nonatomic, nullable, strong) id value;
+@property (nonatomic, nullable, strong) Class valueTransformer;
+@property (nonatomic, assign ) UITableViewCellStyle cellStyle;
+@property (nonatomic, assign ) CGFloat height;
-@property (copy, nullable) XLOnChangeBlock onChangeBlock;
-@property BOOL useValueFormatterDuringInput;
-@property (nullable) NSFormatter *valueFormatter;
+@property (nonatomic, copy , nullable) XLOnChangeBlock onChangeBlock;
+@property (nonatomic, assign) BOOL useValueFormatterDuringInput;
+@property (nonatomic, strong, nullable) NSFormatter *valueFormatter;
// returns the display text for the row descriptor, taking into account NSFormatters and default placeholder values
- (nonnull NSString *) displayTextValue;
@@ -66,20 +66,22 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
// returns the editing text value for the row descriptor, taking into account NSFormatters.
- (nonnull NSString *) editTextValue;
-@property (nonatomic, readonly, nonnull) NSMutableDictionary * cellConfig;
-@property (nonatomic, readonly, nonnull) NSMutableDictionary * 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 (nonnull) XLFormAction * action;
+@property (getter=isRequired, nonatomic, assign) BOOL required;
+
+@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 +89,7 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
-(nonnull XLFormBaseCell *)cellForFormController:(nonnull XLFormViewController *)formController;
-@property (nullable) NSString *requireMsg;
+@property (nonatomic, nullable, copy) NSString *requireMsg;
-(void)addValidator:(nonnull id)validator;
-(void)removeValidator:(nonnull id)validator;
-(nullable XLFormValidationStatus *)doValidation;
@@ -95,9 +97,9 @@ typedef void(^XLOnChangeBlock)(id __nullable oldValue,id __nullable newValue,XLF
// ===========================
// property used for Selectors
// ===========================
-@property (nullable) NSString * noValueDisplayText;
-@property (nullable) NSString * selectorTitle;
-@property (nullable) NSArray * selectorOptions;
+@property (nonatomic, nullable, copy) NSString * noValueDisplayText;
+@property (nonatomic, nullable, copy) NSString * selectorTitle;
+@property (nonatomic, nullable, strong) NSArray * selectorOptions;
@property (null_unspecified) id leftRightSelectorLeftOptionSelected;
@@ -126,13 +128,13 @@ typedef NS_ENUM(NSUInteger, XLFormLeftRightSelectorOptionLeftValueChangePolicy)
@interface XLFormLeftRightSelectorOption : NSObject
@property (nonatomic, assign) XLFormLeftRightSelectorOptionLeftValueChangePolicy leftValueChangePolicy;
-@property (readonly, nonnull) id leftValue;
-@property (readonly, nonnull) NSArray * rightOptions;
-@property (readonly, null_unspecified) NSString * httpParameterKey;
-@property (nullable) Class rightSelectorControllerClass;
+@property (nonatomic, readonly, nonnull) id leftValue;
+@property (nonatomic, readonly, nonnull) NSArray * rightOptions;
+@property (nonatomic, readonly, null_unspecified, copy) NSString * httpParameterKey;
+@property (nonatomic, nullable) Class rightSelectorControllerClass;
-@property (nullable) NSString * noValueDisplayText;
-@property (nullable) NSString * selectorTitle;
+@property (nonatomic, nullable, copy) NSString * noValueDisplayText;
+@property (nonatomic, nullable, copy) NSString * selectorTitle;
+(nonnull XLFormLeftRightSelectorOption *)formLeftRightSelectorOptionWithLeftValue:(nonnull id)leftValue
@@ -154,16 +156,16 @@ typedef NS_ENUM(NSUInteger, XLFormLeftRightSelectorOptionLeftValueChangePolicy)
@interface XLFormAction : NSObject
-@property (nullable, nonatomic, strong) Class viewControllerClass;
-@property (nullable, nonatomic, strong) NSString * viewControllerStoryboardId;
-@property (nullable, nonatomic, strong) NSString * viewControllerNibName;
+@property (nullable, nonatomic) Class viewControllerClass;
+@property (nullable, nonatomic, copy) NSString * viewControllerStoryboardId;
+@property (nullable, nonatomic, copy) NSString * viewControllerNibName;
-@property (nonatomic) XLFormPresentationMode viewControllerPresentationMode;
+@property (nonatomic, assign) XLFormPresentationMode viewControllerPresentationMode;
-@property (nullable, nonatomic, strong) void (^formBlock)(XLFormRowDescriptor * __nonnull sender);
+@property (nullable, nonatomic, copy) void (^formBlock)(XLFormRowDescriptor * __nonnull sender);
@property (nullable, nonatomic) SEL formSelector;
-@property (nullable, nonatomic, strong) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead");
-@property (nullable, nonatomic, strong) NSString * formSegueIdentifier;
-@property (nullable, nonatomic, strong) Class formSegueClass;
+@property (nullable, nonatomic, copy) NSString * formSegueIdenfifier DEPRECATED_ATTRIBUTE DEPRECATED_MSG_ATTRIBUTE("Use formSegueIdentifier instead");
+@property (nullable, nonatomic, copy) NSString * formSegueIdentifier;
+@property (nullable, nonatomic) Class formSegueClass;
@end
diff --git a/XLForm/XL/Descriptors/XLFormRowDescriptor.m b/XLForm/XL/Descriptors/XLFormRowDescriptor.m
index fdd9a114..945c9fd9 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;
@@ -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 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
@@ -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;
}
@@ -161,72 +172,84 @@ -(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];
}];
}
-(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
@@ -236,9 +259,10 @@ -(NSString *)description
-(XLFormAction *)action
{
- if (!_action){
+ if (!_action) {
_action = [[XLFormAction alloc] init];
}
+
return _action;
}
@@ -249,13 +273,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;
}
@@ -266,71 +292,76 @@ -(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) {}
+
+ _cell = nil;
+
+ [self.validators removeAllObjects];
+ self.validators = nil;
}
#pragma mark - KVO
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
- if (!self.sectionDescriptor) return;
- if (object == self && ([keyPath isEqualToString:@"value"] || [keyPath isEqualToString:@"hidePredicateCache"] || [keyPath isEqualToString:@"disablePredicateCache"])){
+ if (!self.sectionDescriptor) {
+ return;
+ }
+ else if (object == self && ([keyPath isEqualToString:XLValueKey] ||
+ [keyPath isEqualToString:XLHidePredicateCacheKey] || [keyPath isEqualToString:XLDisablePredicateCacheKey])) {
if ([[change objectForKey:NSKeyValueChangeKindKey] isEqualToNumber:@(NSKeyValueChangeSetting)]){
id newValue = [change objectForKey:NSKeyValueChangeNewKey];
id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
- if ([keyPath isEqualToString:@"value"]){
+ if ([keyPath isEqualToString:XLValueKey]) {
[self.sectionDescriptor.formDescriptor.delegate formRowDescriptorValueHasChanged:object oldValue:oldValue newValue:newValue];
if (self.onChangeBlock) {
self.onChangeBlock(oldValue, newValue, self);
}
}
- else{
- [self.sectionDescriptor.formDescriptor.delegate formRowDescriptorPredicateHasChanged:object oldValue:oldValue newValue:newValue predicateType:([keyPath isEqualToString:@"hidePredicateCache"] ? XLPredicateTypeHidden : XLPredicateTypeDisabled)];
+ else {
+ [self.sectionDescriptor.formDescriptor.delegate formRowDescriptorPredicateHasChanged:object
+ oldValue:oldValue
+ newValue:newValue
+ predicateType:([keyPath isEqualToString:XLHidePredicateCacheKey] ? XLPredicateTypeHidden : XLPredicateTypeDisabled)];
}
}
}
@@ -340,12 +371,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];
}
@@ -354,11 +387,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];
}
@@ -367,7 +401,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 ?: @{}]);
}
@@ -377,12 +412,14 @@ -(BOOL)evaluateIsDisabled
};
}
}
- else{
+ else {
self.disablePredicateCache = _disabled;
}
- if ([self.disablePredicateCache boolValue]){
+
+ if ([self.disablePredicateCache boolValue]) {
[self.cell resignFirstResponder];
}
+
return [self.disablePredicateCache boolValue];
}
@@ -393,9 +430,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;
}
}
@@ -414,9 +451,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;
}
}
@@ -426,6 +463,7 @@ -(BOOL)isHidden
if (self.isDirtyHidePredicateCache) {
return [self evaluateIsHidden];
}
+
return [self.hidePredicateCache boolValue];
}
@@ -434,7 +472,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 ?: @{}]);
}
@@ -444,16 +483,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];
}
@@ -463,10 +504,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.
}
@@ -480,34 +523,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]) {
@@ -515,22 +559,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
@@ -538,10 +584,12 @@ -(XLFormValidationStatus *)doValidation
return vStatus;
}
valStatus = vStatus;
- } else {
+ }
+ else {
valStatus = nil;
}
}
+
return valStatus;
}
@@ -597,13 +645,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;
}
@@ -614,10 +662,10 @@ @implementation XLFormAction
- (instancetype)init
{
- self = [super init];
- if (self) {
+ if (self = [super init]) {
_viewControllerPresentationMode = XLFormPresentationModeDefault;
}
+
return self;
}
@@ -629,24 +677,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;
}
@@ -671,7 +720,6 @@ -(void)setViewControllerStoryboardId:(NSString *)viewControllerStoryboardId
_viewControllerStoryboardId = viewControllerStoryboardId;
}
-
-(void)setFormSelector:(SEL)formSelector
{
_formBlock = nil;
@@ -680,7 +728,6 @@ -(void)setFormSelector:(SEL)formSelector
_formSelector = formSelector;
}
-
-(void)setFormBlock:(void (^)(XLFormRowDescriptor *))formBlock
{
_formSegueClass = nil;
diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.h b/XLForm/XL/Descriptors/XLFormSectionDescriptor.h
index f0553fdb..f65c0844 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, strong) NSMutableArray * formRows;
-@property (readonly) XLFormSectionInsertMode sectionInsertMode;
-@property (readonly) XLFormSectionOptions sectionOptions;
-@property (nullable) XLFormRowDescriptor * multivaluedRowTemplate;
-@property (readonly, nullable) XLFormRowDescriptor * multivaluedAddButton;
-@property (nonatomic, nullable) NSString * multivaluedTag;
+@property (nonatomic, readonly, assign) XLFormSectionInsertMode sectionInsertMode;
+@property (nonatomic, readonly, assign) XLFormSectionOptions sectionOptions;
+@property (nonatomic, nullable, strong) XLFormRowDescriptor * multivaluedRowTemplate;
+@property (nonatomic, readonly, nullable, strong) XLFormRowDescriptor * multivaluedAddButton;
+@property (nonatomic, nullable, copy) NSString * multivaluedTag;
-@property (weak, null_unspecified) XLFormDescriptor * formDescriptor;
+@property (nonatomic, weak, null_unspecified) XLFormDescriptor * formDescriptor;
-@property (nonnull) id hidden;
+@property (nonatomic, nonnull, strong) id hidden;
-(BOOL)isHidden;
+(nonnull instancetype)formSection;
diff --git a/XLForm/XL/Descriptors/XLFormSectionDescriptor.m b/XLForm/XL/Descriptors/XLFormSectionDescriptor.m
index e51e7e52..ee8d5cc0 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 (readonly) NSDictionary* allRowsByTag;
+@property (nonatomic, weak, readonly) NSDictionary *allRowsByTag;
--(void)addRowToTagCollection:(XLFormRowDescriptor*)rowDescriptor;
--(void)removeRowFromTagCollection:(XLFormRowDescriptor*) rowDescriptor;
--(void)showFormSection:(XLFormSectionDescriptor*)formSection;
--(void)hideFormSection:(XLFormSectionDescriptor*)formSection;
+-(void)addRowToTagCollection:(XLFormRowDescriptor *)rowDescriptor;
+-(void)removeRowFromTagCollection:(XLFormRowDescriptor *) rowDescriptor;
+-(void)showFormSection:(XLFormSectionDescriptor *)formSection;
+-(void)hideFormSection:(XLFormSectionDescriptor *)formSection;
-(void)addObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
-(void)removeObserversOfObject:(id)sectionOrRow predicateType:(XLPredicateType)predicateType;
@@ -46,10 +47,11 @@ -(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
@@ -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,15 @@ - (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;
+
+ [self.allRows removeAllObjects];
+ self.allRows = nil;
}
#pragma mark - Show/hide rows
@@ -214,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 {
@@ -232,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
@@ -342,9 +359,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;
}
}
@@ -354,6 +371,7 @@ -(BOOL)isHidden
if (self.isDirtyHidePredicateCache) {
return [self evaluateIsHidden];
}
+
return [self.hidePredicateCache boolValue];
}
@@ -362,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 ?: @{}]);
}
@@ -372,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];
}
@@ -398,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.
}
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..c2bc45a6 100644
--- a/XLForm/XL/Helpers/UIView+XLFormAdditions.m
+++ b/XLForm/XL/Helpers/UIView+XLFormAdditions.m
@@ -27,47 +27,62 @@
@implementation UIView (XLFormAdditions)
-+ (id)autolayoutView
++ (instancetype)autolayoutView
{
- UIView *view = [self new];
+ __kindof UIView *view = [self new];
view.translatesAutoresizingMaskIntoConstraints = NO;
+
return view;
}
--(NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view
+- (NSLayoutConstraint *)layoutConstraintSameHeightOf:(UIView *)view
{
- return [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
+ return [NSLayoutConstraint constraintWithItem:self
+ attribute:NSLayoutAttributeHeight
+ relatedBy:NSLayoutRelationEqual
+ toItem:view
+ attribute:NSLayoutAttributeHeight
+ multiplier:1.0
+ constant:0.0];
}
- (UIView *)findFirstResponder
{
+ UIView *firstResponder = nil;
if (self.isFirstResponder) {
- return self;
+ firstResponder = self;
}
- for (UIView *subView in self.subviews) {
- UIView *firstResponder = [subView findFirstResponder];
- if (firstResponder != nil) {
- return firstResponder;
+ else {
+ for (UIView *subView in self.subviews) {
+ UIView *fr = [subView findFirstResponder];
+ if (fr != nil) {
+ firstResponder = fr;
+
+ break;
+ }
}
}
- return nil;
+
+ return firstResponder;
}
- (UITableViewCell *)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
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
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 a5b2a70f..df2cf897 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
@@ -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;