Skip to content

Commit bb4a448

Browse files
committed
Textfield validation: save to settings if validation is OK
should improve crash recovery and lets the delegate indicate validation errors in real time; .okWithReplacement validation results are immediately performed instead of waiting for focus loss;
1 parent b60959a commit bb4a448

File tree

4 files changed

+39
-22
lines changed

4 files changed

+39
-22
lines changed

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.3.2
1+
3.4.5

InAppSettingsKit.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'InAppSettingsKit'
3-
s.version = '3.8.5'
3+
s.version = '3.8.6'
44
s.summary = 'This iPhone framework allows settings to be in-app in addition to being in the Settings app.'
55

66
s.description = <<-DESC

InAppSettingsKitSampleApp/Classes/MainViewController.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ extension MainViewController: IASKSettingsDelegate {
7575
textField: IASKTextField,
7676
previousValue: String?,
7777
replacement: AutoreleasingUnsafeMutablePointer<NSString>?) -> IASKValidationResult {
78-
guard let key = specifier.key else { return .ok }
78+
guard let key = specifier.key,
79+
let newText = replacement?.pointee else {
80+
return .ok
81+
}
7982
if key.starts(with: "RegexValidation") {
80-
if textField.text == "" || textField.text?.range(of: #".+\@.+"#, options: .regularExpression) != nil {
83+
if newText == "" || newText.range(of: #".+\@.+"#, options: .regularExpression).location != NSNotFound {
8184
if #available(iOS 13.0, *) {
8285
textField.textColor = .label
8386
} else {
@@ -86,26 +89,26 @@ extension MainViewController: IASKSettingsDelegate {
8689
return .ok
8790
}
8891
if key != "RegexValidation2" {
89-
let myReplacement: String = ((previousValue?.lengthOfBytes(using: .utf8) ?? 0) > 0 ? previousValue : textField.text) ?? ""
92+
let myReplacement: String = (previousValue?.lengthOfBytes(using: .utf8) ?? 0) > 0 ? previousValue ?? "" : newText as String
9093
replacement?.pointee = myReplacement as NSString
9194
return .failedWithShake
9295
}
9396
textField.textColor = .red
9497
return .failed
95-
} else if key == "account_name", let value = textField.text {
98+
} else if key == "account_name" {
9699
let regex = "^@?[\\w](?!.*?\\.{2})[\\w.]{1,28}[\\w]$"
97-
if value.isEmpty {
98-
return .okWithReplacement
99-
} else if value == "@" {
100+
if newText == "" {
101+
return .ok
102+
} else if newText == "@" {
100103
replacement?.pointee = "" as NSString
101104
return .failed
102-
} else if value.range(of: regex, options: .regularExpression) == nil {
105+
} else if newText.range(of: regex, options: .regularExpression).location == NSNotFound {
103106
if let previousValue {
104107
replacement?.pointee = previousValue as NSString
105108
return .failedWithShake
106109
}
107-
} else if !value.hasPrefix("@") {
108-
replacement?.pointee = "@\(value)" as NSString
110+
} else if !newText.hasPrefix("@") {
111+
replacement?.pointee = "@\(newText)" as NSString
109112
return .okWithReplacement
110113
}
111114
}

Sources/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,6 @@ - (UITableViewCell*)tableView:(UITableView *)tableView newCellForSpecifier:(IASK
589589
}
590590
else if ([identifier hasPrefix:kIASKPSTextFieldSpecifier]) {
591591
cell = [[IASKPSTextFieldSpecifierViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
592-
[((IASKPSTextFieldSpecifierViewCell*)cell).textField addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];
593592
}
594593
else if ([identifier hasPrefix:kIASKTextViewSpecifier]) {
595594
cell = [[IASKTextViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
@@ -1181,17 +1180,32 @@ - (void)textFieldDidBeginEditing:(UITextField *)textField {
11811180
self.currentFirstResponder = textField;
11821181
}
11831182

1184-
- (void)textChanged:(IASKTextField*)textField {
1183+
- (BOOL)textField:(IASKTextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)replacementString {
1184+
NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:replacementString];
11851185
// Wait with setting the property until editing ends for the addSpecifier of list groups or if a validation delegate is implemented
1186-
if ((!textField.specifier.isAddSpecifier && ![self.delegate respondsToSelector:@selector(settingsViewController:validateSpecifier:textField:previousValue:replacement:)]) ||
1186+
IASKValidationResult result = IASKValidationResultOk;
1187+
if ((!textField.specifier.isAddSpecifier) ||
11871188
(self.listParentViewController && [self.delegate respondsToSelector:@selector(settingsViewController:childPaneIsValidForSpecifier:contentDictionary:)]))
11881189
{
1189-
[self.settingsStore setObject:textField.text forSpecifier:textField.specifier];
1190-
NSDictionary *userInfo = textField.specifier.key && textField.text ? @{(id)textField.specifier.key : (NSString *)textField.text} : nil;
1191-
[NSNotificationCenter.defaultCenter postNotificationName:kIASKAppSettingChanged
1192-
object:self
1193-
userInfo:userInfo];
1194-
}
1190+
BOOL storeToSettings = YES;
1191+
if (!textField.specifier.isAddSpecifier && [self.delegate respondsToSelector:@selector(settingsViewController:validateSpecifier:textField:previousValue:replacement:)]) {
1192+
result = [self.delegate settingsViewController:self validateSpecifier:textField.specifier textField:textField previousValue:textField.text replacement:&newText];
1193+
if (result == IASKValidationResultOkWithReplacement) {
1194+
storeToSettings = NO;
1195+
textField.text = newText;
1196+
} else if (result != IASKValidationResultOk) {
1197+
storeToSettings = NO;
1198+
}
1199+
}
1200+
if (storeToSettings) {
1201+
[self.settingsStore setObject:newText forSpecifier:textField.specifier];
1202+
NSDictionary *userInfo = textField.specifier.key && newText ? @{(id)textField.specifier.key : newText} : nil;
1203+
[NSNotificationCenter.defaultCenter postNotificationName:kIASKAppSettingChanged
1204+
object:self
1205+
userInfo:userInfo];
1206+
}
1207+
}
1208+
return result != IASKValidationResultOkWithReplacement;
11951209
}
11961210

11971211
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
@@ -1216,7 +1230,7 @@ - (void)textFieldDidEndEditing:(IASKTextField *)textField {
12161230
void (^restoreText)(void) = ^{
12171231
if (![textField.text isEqualToString:replacement]) {
12181232
textField.text = replacement;
1219-
[self textChanged:textField];
1233+
[self textField:textField shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
12201234
}
12211235
};
12221236

0 commit comments

Comments
 (0)