UISwitch value changed event fires before UITextField editing did end
In my application there are many UISwitch
es and UITextField
s displayed in a list of UITableViewCell
s.
When the user starts editing a UITextField
and then taps on a UISwitch
the order of the events causes the UITextField
to display the value of the UISwitch
because the event handler did not receive the end editing event of the UITextField
.
How to ensure reliably that the UIControlEventEditingDidEnd
event of the UITextField
gets fired before the UIControlEventValueChanged
of the UISwitch
?
It leads to errors like this (value of switch displayed in text field):
Steps (what should happen):
1.Tap the UISwitch
to activate it
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
2.Tap the UITextField
to start editing it
UITextField:startEditing:textfield455
3.Tap the UISwitch
to deactivate it
UITextField:endEditing
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
Console log (what really happens - the UISwitch event fires before UITextField:endEditing):
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
UITextField:startEditing:textfield455
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
UITextField:endEditing
Implementation:
UITableViewCellWithSwitch.h
:
@interface UITableViewCellWithSwitch : UITableViewCell
@property (nonatomic, strong) NSString *attributeID;
@property (nonatomic, retain) IBOutlet UISwitch *switchField;
@end
UITableViewCellWithSwitch.m
:
@implementation UITableViewCellWithSwitch
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.switchField addTarget:self
action:@selector(switchChanged:)
forControlEvents:UIControlEventValueChanged];
}
return self;
}
// UIControlEventValueChanged
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UITableViewCellWithTextField.h
:
@interface UITableViewCellWithTextField : UITableViewCell<UITextFieldDelegate>
@property (nonatomic, strong) NSString *attributeID;
@property (strong, nonatomic) IBOutlet UITextField *inputField;
@end
UITableViewCellWithTextField.m
:
@implementation UITableViewCellWithTextField
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.inputField addTarget:self
action:@selector(textFieldDidBegin:)
forControlEvents:UIControlEventEditingDidBegin];
[self.inputField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
[self.inputField addTarget:self
action:@selector(textFieldDidEnd:)
forControlEvents:UIControlEventEditingDidEnd];
}
return self;
}
// UIControlEventEditingDidBegin
-(void) textFieldDidBegin:(UITextField *)sender {
NSLog(@"UITextField:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
}
// UIControlEventEditingChanged
-(void) textFieldDidChange:(UITextField *)sender {
NSLog(@"UITextField:valueChanged:{%@}", sender.text);
[self handleValueChangeForEditedAttribute:sender.text];
}
// UIControlEventEditingDidEnd
-(void) textFieldDidEnd:(UITextField *)sender {
NSLog(@"UITextField:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UIEventHandler.m
that aggregates all UI editing events:
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
//if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
// [self handleEndEditingForActiveAttribute];
//}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
ios uitextfield uikit uiswitch uicontrolevents
|
show 2 more comments
In my application there are many UISwitch
es and UITextField
s displayed in a list of UITableViewCell
s.
When the user starts editing a UITextField
and then taps on a UISwitch
the order of the events causes the UITextField
to display the value of the UISwitch
because the event handler did not receive the end editing event of the UITextField
.
How to ensure reliably that the UIControlEventEditingDidEnd
event of the UITextField
gets fired before the UIControlEventValueChanged
of the UISwitch
?
It leads to errors like this (value of switch displayed in text field):
Steps (what should happen):
1.Tap the UISwitch
to activate it
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
2.Tap the UITextField
to start editing it
UITextField:startEditing:textfield455
3.Tap the UISwitch
to deactivate it
UITextField:endEditing
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
Console log (what really happens - the UISwitch event fires before UITextField:endEditing):
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
UITextField:startEditing:textfield455
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
UITextField:endEditing
Implementation:
UITableViewCellWithSwitch.h
:
@interface UITableViewCellWithSwitch : UITableViewCell
@property (nonatomic, strong) NSString *attributeID;
@property (nonatomic, retain) IBOutlet UISwitch *switchField;
@end
UITableViewCellWithSwitch.m
:
@implementation UITableViewCellWithSwitch
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.switchField addTarget:self
action:@selector(switchChanged:)
forControlEvents:UIControlEventValueChanged];
}
return self;
}
// UIControlEventValueChanged
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UITableViewCellWithTextField.h
:
@interface UITableViewCellWithTextField : UITableViewCell<UITextFieldDelegate>
@property (nonatomic, strong) NSString *attributeID;
@property (strong, nonatomic) IBOutlet UITextField *inputField;
@end
UITableViewCellWithTextField.m
:
@implementation UITableViewCellWithTextField
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.inputField addTarget:self
action:@selector(textFieldDidBegin:)
forControlEvents:UIControlEventEditingDidBegin];
[self.inputField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
[self.inputField addTarget:self
action:@selector(textFieldDidEnd:)
forControlEvents:UIControlEventEditingDidEnd];
}
return self;
}
// UIControlEventEditingDidBegin
-(void) textFieldDidBegin:(UITextField *)sender {
NSLog(@"UITextField:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
}
// UIControlEventEditingChanged
-(void) textFieldDidChange:(UITextField *)sender {
NSLog(@"UITextField:valueChanged:{%@}", sender.text);
[self handleValueChangeForEditedAttribute:sender.text];
}
// UIControlEventEditingDidEnd
-(void) textFieldDidEnd:(UITextField *)sender {
NSLog(@"UITextField:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UIEventHandler.m
that aggregates all UI editing events:
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
//if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
// [self handleEndEditingForActiveAttribute];
//}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
ios uitextfield uikit uiswitch uicontrolevents
1
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used byUIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have twotextFieldDidBegin
methods? Also, nothing to indicate wheresender.attributeID
is coming from?
– DonMag
Nov 20 '18 at 16:24
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39
|
show 2 more comments
In my application there are many UISwitch
es and UITextField
s displayed in a list of UITableViewCell
s.
When the user starts editing a UITextField
and then taps on a UISwitch
the order of the events causes the UITextField
to display the value of the UISwitch
because the event handler did not receive the end editing event of the UITextField
.
How to ensure reliably that the UIControlEventEditingDidEnd
event of the UITextField
gets fired before the UIControlEventValueChanged
of the UISwitch
?
It leads to errors like this (value of switch displayed in text field):
Steps (what should happen):
1.Tap the UISwitch
to activate it
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
2.Tap the UITextField
to start editing it
UITextField:startEditing:textfield455
3.Tap the UISwitch
to deactivate it
UITextField:endEditing
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
Console log (what really happens - the UISwitch event fires before UITextField:endEditing):
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
UITextField:startEditing:textfield455
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
UITextField:endEditing
Implementation:
UITableViewCellWithSwitch.h
:
@interface UITableViewCellWithSwitch : UITableViewCell
@property (nonatomic, strong) NSString *attributeID;
@property (nonatomic, retain) IBOutlet UISwitch *switchField;
@end
UITableViewCellWithSwitch.m
:
@implementation UITableViewCellWithSwitch
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.switchField addTarget:self
action:@selector(switchChanged:)
forControlEvents:UIControlEventValueChanged];
}
return self;
}
// UIControlEventValueChanged
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UITableViewCellWithTextField.h
:
@interface UITableViewCellWithTextField : UITableViewCell<UITextFieldDelegate>
@property (nonatomic, strong) NSString *attributeID;
@property (strong, nonatomic) IBOutlet UITextField *inputField;
@end
UITableViewCellWithTextField.m
:
@implementation UITableViewCellWithTextField
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.inputField addTarget:self
action:@selector(textFieldDidBegin:)
forControlEvents:UIControlEventEditingDidBegin];
[self.inputField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
[self.inputField addTarget:self
action:@selector(textFieldDidEnd:)
forControlEvents:UIControlEventEditingDidEnd];
}
return self;
}
// UIControlEventEditingDidBegin
-(void) textFieldDidBegin:(UITextField *)sender {
NSLog(@"UITextField:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
}
// UIControlEventEditingChanged
-(void) textFieldDidChange:(UITextField *)sender {
NSLog(@"UITextField:valueChanged:{%@}", sender.text);
[self handleValueChangeForEditedAttribute:sender.text];
}
// UIControlEventEditingDidEnd
-(void) textFieldDidEnd:(UITextField *)sender {
NSLog(@"UITextField:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UIEventHandler.m
that aggregates all UI editing events:
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
//if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
// [self handleEndEditingForActiveAttribute];
//}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
ios uitextfield uikit uiswitch uicontrolevents
In my application there are many UISwitch
es and UITextField
s displayed in a list of UITableViewCell
s.
When the user starts editing a UITextField
and then taps on a UISwitch
the order of the events causes the UITextField
to display the value of the UISwitch
because the event handler did not receive the end editing event of the UITextField
.
How to ensure reliably that the UIControlEventEditingDidEnd
event of the UITextField
gets fired before the UIControlEventValueChanged
of the UISwitch
?
It leads to errors like this (value of switch displayed in text field):
Steps (what should happen):
1.Tap the UISwitch
to activate it
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
2.Tap the UITextField
to start editing it
UITextField:startEditing:textfield455
3.Tap the UISwitch
to deactivate it
UITextField:endEditing
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
Console log (what really happens - the UISwitch event fires before UITextField:endEditing):
UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}
UITextField:startEditing:textfield455
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}
UITextField:endEditing
Implementation:
UITableViewCellWithSwitch.h
:
@interface UITableViewCellWithSwitch : UITableViewCell
@property (nonatomic, strong) NSString *attributeID;
@property (nonatomic, retain) IBOutlet UISwitch *switchField;
@end
UITableViewCellWithSwitch.m
:
@implementation UITableViewCellWithSwitch
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.switchField addTarget:self
action:@selector(switchChanged:)
forControlEvents:UIControlEventValueChanged];
}
return self;
}
// UIControlEventValueChanged
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UITableViewCellWithTextField.h
:
@interface UITableViewCellWithTextField : UITableViewCell<UITextFieldDelegate>
@property (nonatomic, strong) NSString *attributeID;
@property (strong, nonatomic) IBOutlet UITextField *inputField;
@end
UITableViewCellWithTextField.m
:
@implementation UITableViewCellWithTextField
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.inputField addTarget:self
action:@selector(textFieldDidBegin:)
forControlEvents:UIControlEventEditingDidBegin];
[self.inputField addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
[self.inputField addTarget:self
action:@selector(textFieldDidEnd:)
forControlEvents:UIControlEventEditingDidEnd];
}
return self;
}
// UIControlEventEditingDidBegin
-(void) textFieldDidBegin:(UITextField *)sender {
NSLog(@"UITextField:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
}
// UIControlEventEditingChanged
-(void) textFieldDidChange:(UITextField *)sender {
NSLog(@"UITextField:valueChanged:{%@}", sender.text);
[self handleValueChangeForEditedAttribute:sender.text];
}
// UIControlEventEditingDidEnd
-(void) textFieldDidEnd:(UITextField *)sender {
NSLog(@"UITextField:endEditing");
[self handleEndEditingForEditedAttribute];
}
@end
UIEventHandler.m
that aggregates all UI editing events:
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
//if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
// [self handleEndEditingForActiveAttribute];
//}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
ios uitextfield uikit uiswitch uicontrolevents
ios uitextfield uikit uiswitch uicontrolevents
edited Nov 21 '18 at 8:21
Peter Gerhat
asked Nov 20 '18 at 14:22
Peter GerhatPeter Gerhat
3,11274283
3,11274283
1
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used byUIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have twotextFieldDidBegin
methods? Also, nothing to indicate wheresender.attributeID
is coming from?
– DonMag
Nov 20 '18 at 16:24
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39
|
show 2 more comments
1
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used byUIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have twotextFieldDidBegin
methods? Also, nothing to indicate wheresender.attributeID
is coming from?
– DonMag
Nov 20 '18 at 16:24
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39
1
1
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used by
UIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used by
UIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have two
textFieldDidBegin
methods? Also, nothing to indicate where sender.attributeID
is coming from?– DonMag
Nov 20 '18 at 16:24
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have two
textFieldDidBegin
methods? Also, nothing to indicate where sender.attributeID
is coming from?– DonMag
Nov 20 '18 at 16:24
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39
|
show 2 more comments
2 Answers
2
active
oldest
votes
If I understand correctly, the problem you're having is when the switch value is changed while a textfield is the first responder, then your textfield's text gets updated to the value of the switch.
A UITextField
's didEndEditing:
event only happens if the textfield resigns first responder. If all you want to do is to make sure that the textfield ends editing when the switch value changes, you should send the endEditing:
message to the active textfield when the switch receives a UIControlEventValueChanged
event.
Now how you call the endEditing:
message on the text field depends on the structure of your classes. You could have a designated initializer method on your table view cell class where you pass an instance of the UITextField
corresponding to the UISwitch
that controls the text field. Keep a weak reference to the textfield instance and then call endEditing:
when the switch value changes. Or you could simply try to call [self endEditing:YES];
on the UITableViewCellWithSwitch
when switchChanged:
event is fired or [self.superview endEditing:YES];
. I prefer the former solution rather than the latter since the latter is more of a hack than a proper solution.
UPDATE:
After reviewing your code, the reason for the error you've mentioned in your question
It leads to errors like this (value of switch displayed in text field):
is the following piece of code:
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
You are calling the handleValueChangeForEditedAttribute:
with the switch's value for the attribute that is only supposed to hold the textfield's value in reality. And in your UIEventHandler
class you are updating your data access object (DAO) with the switch value in the handleEndEditingForEditedAttribute
method. Change your switchChanged:
method's logic to something like this:
- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}
And in your UIEventHandler
class, uncomment the commented lines in your post that say "possible solution". That should ensure any previous changes to get saved before storing values for the new attributeID
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
That is correct[self.storage saveValue]
causes the whole view to regenerate, which causes theUITextField
to lose first responder status and trigger theUIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in theUIEventHandler.m
(see possible solution).
– Peter Gerhat
Nov 20 '18 at 17:02
1
@PeterGerhat You're right. Check out my updated answer. I updated yourswitchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea howswitchChanged:
should work. It has to trigger thestartEditing
,valueChanged
andendEditing
events in that sequence for theUIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it forUISwitch
exclusively.
– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling[self.view endEditing:YES]
in your table view cell or its parent view to trigger theUITextField
's did end editing event.
– Pranay
Nov 26 '18 at 16:19
add a comment |
My best solution yet was to solve the problem in UIEventHandler.m
. If at the time of calling startEditing
the endEditing
event wasn't triggered yet it gets called from the UIEventHandler
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395076%2fuiswitch-value-changed-event-fires-before-uitextfield-editing-did-end%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If I understand correctly, the problem you're having is when the switch value is changed while a textfield is the first responder, then your textfield's text gets updated to the value of the switch.
A UITextField
's didEndEditing:
event only happens if the textfield resigns first responder. If all you want to do is to make sure that the textfield ends editing when the switch value changes, you should send the endEditing:
message to the active textfield when the switch receives a UIControlEventValueChanged
event.
Now how you call the endEditing:
message on the text field depends on the structure of your classes. You could have a designated initializer method on your table view cell class where you pass an instance of the UITextField
corresponding to the UISwitch
that controls the text field. Keep a weak reference to the textfield instance and then call endEditing:
when the switch value changes. Or you could simply try to call [self endEditing:YES];
on the UITableViewCellWithSwitch
when switchChanged:
event is fired or [self.superview endEditing:YES];
. I prefer the former solution rather than the latter since the latter is more of a hack than a proper solution.
UPDATE:
After reviewing your code, the reason for the error you've mentioned in your question
It leads to errors like this (value of switch displayed in text field):
is the following piece of code:
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
You are calling the handleValueChangeForEditedAttribute:
with the switch's value for the attribute that is only supposed to hold the textfield's value in reality. And in your UIEventHandler
class you are updating your data access object (DAO) with the switch value in the handleEndEditingForEditedAttribute
method. Change your switchChanged:
method's logic to something like this:
- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}
And in your UIEventHandler
class, uncomment the commented lines in your post that say "possible solution". That should ensure any previous changes to get saved before storing values for the new attributeID
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
That is correct[self.storage saveValue]
causes the whole view to regenerate, which causes theUITextField
to lose first responder status and trigger theUIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in theUIEventHandler.m
(see possible solution).
– Peter Gerhat
Nov 20 '18 at 17:02
1
@PeterGerhat You're right. Check out my updated answer. I updated yourswitchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea howswitchChanged:
should work. It has to trigger thestartEditing
,valueChanged
andendEditing
events in that sequence for theUIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it forUISwitch
exclusively.
– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling[self.view endEditing:YES]
in your table view cell or its parent view to trigger theUITextField
's did end editing event.
– Pranay
Nov 26 '18 at 16:19
add a comment |
If I understand correctly, the problem you're having is when the switch value is changed while a textfield is the first responder, then your textfield's text gets updated to the value of the switch.
A UITextField
's didEndEditing:
event only happens if the textfield resigns first responder. If all you want to do is to make sure that the textfield ends editing when the switch value changes, you should send the endEditing:
message to the active textfield when the switch receives a UIControlEventValueChanged
event.
Now how you call the endEditing:
message on the text field depends on the structure of your classes. You could have a designated initializer method on your table view cell class where you pass an instance of the UITextField
corresponding to the UISwitch
that controls the text field. Keep a weak reference to the textfield instance and then call endEditing:
when the switch value changes. Or you could simply try to call [self endEditing:YES];
on the UITableViewCellWithSwitch
when switchChanged:
event is fired or [self.superview endEditing:YES];
. I prefer the former solution rather than the latter since the latter is more of a hack than a proper solution.
UPDATE:
After reviewing your code, the reason for the error you've mentioned in your question
It leads to errors like this (value of switch displayed in text field):
is the following piece of code:
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
You are calling the handleValueChangeForEditedAttribute:
with the switch's value for the attribute that is only supposed to hold the textfield's value in reality. And in your UIEventHandler
class you are updating your data access object (DAO) with the switch value in the handleEndEditingForEditedAttribute
method. Change your switchChanged:
method's logic to something like this:
- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}
And in your UIEventHandler
class, uncomment the commented lines in your post that say "possible solution". That should ensure any previous changes to get saved before storing values for the new attributeID
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
That is correct[self.storage saveValue]
causes the whole view to regenerate, which causes theUITextField
to lose first responder status and trigger theUIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in theUIEventHandler.m
(see possible solution).
– Peter Gerhat
Nov 20 '18 at 17:02
1
@PeterGerhat You're right. Check out my updated answer. I updated yourswitchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea howswitchChanged:
should work. It has to trigger thestartEditing
,valueChanged
andendEditing
events in that sequence for theUIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it forUISwitch
exclusively.
– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling[self.view endEditing:YES]
in your table view cell or its parent view to trigger theUITextField
's did end editing event.
– Pranay
Nov 26 '18 at 16:19
add a comment |
If I understand correctly, the problem you're having is when the switch value is changed while a textfield is the first responder, then your textfield's text gets updated to the value of the switch.
A UITextField
's didEndEditing:
event only happens if the textfield resigns first responder. If all you want to do is to make sure that the textfield ends editing when the switch value changes, you should send the endEditing:
message to the active textfield when the switch receives a UIControlEventValueChanged
event.
Now how you call the endEditing:
message on the text field depends on the structure of your classes. You could have a designated initializer method on your table view cell class where you pass an instance of the UITextField
corresponding to the UISwitch
that controls the text field. Keep a weak reference to the textfield instance and then call endEditing:
when the switch value changes. Or you could simply try to call [self endEditing:YES];
on the UITableViewCellWithSwitch
when switchChanged:
event is fired or [self.superview endEditing:YES];
. I prefer the former solution rather than the latter since the latter is more of a hack than a proper solution.
UPDATE:
After reviewing your code, the reason for the error you've mentioned in your question
It leads to errors like this (value of switch displayed in text field):
is the following piece of code:
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
You are calling the handleValueChangeForEditedAttribute:
with the switch's value for the attribute that is only supposed to hold the textfield's value in reality. And in your UIEventHandler
class you are updating your data access object (DAO) with the switch value in the handleEndEditingForEditedAttribute
method. Change your switchChanged:
method's logic to something like this:
- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}
And in your UIEventHandler
class, uncomment the commented lines in your post that say "possible solution". That should ensure any previous changes to get saved before storing values for the new attributeID
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
If I understand correctly, the problem you're having is when the switch value is changed while a textfield is the first responder, then your textfield's text gets updated to the value of the switch.
A UITextField
's didEndEditing:
event only happens if the textfield resigns first responder. If all you want to do is to make sure that the textfield ends editing when the switch value changes, you should send the endEditing:
message to the active textfield when the switch receives a UIControlEventValueChanged
event.
Now how you call the endEditing:
message on the text field depends on the structure of your classes. You could have a designated initializer method on your table view cell class where you pass an instance of the UITextField
corresponding to the UISwitch
that controls the text field. Keep a weak reference to the textfield instance and then call endEditing:
when the switch value changes. Or you could simply try to call [self endEditing:YES];
on the UITableViewCellWithSwitch
when switchChanged:
event is fired or [self.superview endEditing:YES];
. I prefer the former solution rather than the latter since the latter is more of a hack than a proper solution.
UPDATE:
After reviewing your code, the reason for the error you've mentioned in your question
It leads to errors like this (value of switch displayed in text field):
is the following piece of code:
- (void)switchChanged:(UISwitch *)sender {
NSLog(@"UISwitch:startEditing:%@",self.attributeID);
[self handleStartEditingForAttributeID:self.attributeID];
NSString* newValue = sender.on==YES?@"true":@"false";
NSLog(@"UISwitch:valueChanged:{%@}", newValue);
[self handleValueChangeForEditedAttribute:newValue];
NSLog(@"UISwitch:endEditing");
[self handleEndEditingForEditedAttribute];
}
You are calling the handleValueChangeForEditedAttribute:
with the switch's value for the attribute that is only supposed to hold the textfield's value in reality. And in your UIEventHandler
class you are updating your data access object (DAO) with the switch value in the handleEndEditingForEditedAttribute
method. Change your switchChanged:
method's logic to something like this:
- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}
And in your UIEventHandler
class, uncomment the commented lines in your post that say "possible solution". That should ensure any previous changes to get saved before storing values for the new attributeID
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
edited Nov 20 '18 at 17:06
answered Nov 20 '18 at 16:51
PranayPranay
53616
53616
That is correct[self.storage saveValue]
causes the whole view to regenerate, which causes theUITextField
to lose first responder status and trigger theUIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in theUIEventHandler.m
(see possible solution).
– Peter Gerhat
Nov 20 '18 at 17:02
1
@PeterGerhat You're right. Check out my updated answer. I updated yourswitchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea howswitchChanged:
should work. It has to trigger thestartEditing
,valueChanged
andendEditing
events in that sequence for theUIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it forUISwitch
exclusively.
– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling[self.view endEditing:YES]
in your table view cell or its parent view to trigger theUITextField
's did end editing event.
– Pranay
Nov 26 '18 at 16:19
add a comment |
That is correct[self.storage saveValue]
causes the whole view to regenerate, which causes theUITextField
to lose first responder status and trigger theUIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in theUIEventHandler.m
(see possible solution).
– Peter Gerhat
Nov 20 '18 at 17:02
1
@PeterGerhat You're right. Check out my updated answer. I updated yourswitchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea howswitchChanged:
should work. It has to trigger thestartEditing
,valueChanged
andendEditing
events in that sequence for theUIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it forUISwitch
exclusively.
– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling[self.view endEditing:YES]
in your table view cell or its parent view to trigger theUITextField
's did end editing event.
– Pranay
Nov 26 '18 at 16:19
That is correct
[self.storage saveValue]
causes the whole view to regenerate, which causes the UITextField
to lose first responder status and trigger the UIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in the UIEventHandler.m
(see possible solution).– Peter Gerhat
Nov 20 '18 at 17:02
That is correct
[self.storage saveValue]
causes the whole view to regenerate, which causes the UITextField
to lose first responder status and trigger the UIControlEventEditingDidEnd
when it is too late. I am starting to think that due to the architecture of my application the best place to solve it is in the UIEventHandler.m
(see possible solution).– Peter Gerhat
Nov 20 '18 at 17:02
1
1
@PeterGerhat You're right. Check out my updated answer. I updated your
switchChanged:
– Pranay
Nov 20 '18 at 17:07
@PeterGerhat You're right. Check out my updated answer. I updated your
switchChanged:
– Pranay
Nov 20 '18 at 17:07
Seems like you didn't get the idea how
switchChanged:
should work. It has to trigger the startEditing
, valueChanged
and endEditing
events in that sequence for the UIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it for UISwitch
exclusively.– Peter Gerhat
Nov 22 '18 at 8:28
Seems like you didn't get the idea how
switchChanged:
should work. It has to trigger the startEditing
, valueChanged
and endEditing
events in that sequence for the UIEventHandler
to work properly. I use this event model across many different UI input components so I can't adapt it for UISwitch
exclusively.– Peter Gerhat
Nov 22 '18 at 8:28
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling
[self.view endEditing:YES]
in your table view cell or its parent view to trigger the UITextField
's did end editing event.– Pranay
Nov 26 '18 at 16:19
@PeterGerhat Ah got it. Well if this design is universal across your app I'd say your best bet is the solution you posted below or calling
[self.view endEditing:YES]
in your table view cell or its parent view to trigger the UITextField
's did end editing event.– Pranay
Nov 26 '18 at 16:19
add a comment |
My best solution yet was to solve the problem in UIEventHandler.m
. If at the time of calling startEditing
the endEditing
event wasn't triggered yet it gets called from the UIEventHandler
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
add a comment |
My best solution yet was to solve the problem in UIEventHandler.m
. If at the time of calling startEditing
the endEditing
event wasn't triggered yet it gets called from the UIEventHandler
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
add a comment |
My best solution yet was to solve the problem in UIEventHandler.m
. If at the time of calling startEditing
the endEditing
event wasn't triggered yet it gets called from the UIEventHandler
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
My best solution yet was to solve the problem in UIEventHandler.m
. If at the time of calling startEditing
the endEditing
event wasn't triggered yet it gets called from the UIEventHandler
.
-(void) handleStartEditingForAttributeID:(NSString *)attributeID {
// Possible solution
if (self.editedAttributeID != nil && [attributeID isEqualToString:self.editedAttributeID]==NO) { // Workaround needed for UISwitch events
[self handleEndEditingForActiveAttribute];
}
self.editedAttributeID = attributeID;
self.temporaryValue = nil;
}
-(void) handleValueChangeForEditedAttribute:(NSString *)newValue {
self.temporaryValue = newValue;
}
-(void) handleEndEditingForEditedAttribute {
if (self.temporaryValue != nil) { // Only if value has changed
NSLog(@"UIEventHandler:saveValue:%@:{%@}", self.editedAttributeID, self.temporaryValue);
// Causes the view to regenerate
// The UITextField loses first responder status and UIControlEventEditingDidEnd is gets triggered too late
[self.storage saveValue:self.temporaryValue
forAttribute:self.editedAttributeID];
self.temporaryValue = nil;
}
self.editedAttributeID = nil;
}
answered Nov 22 '18 at 8:30
Peter GerhatPeter Gerhat
3,11274283
3,11274283
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395076%2fuiswitch-value-changed-event-fires-before-uitextfield-editing-did-end%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You need to provide more information about what your code is doing. From what you've shown, tapping the switch to "deactivate it" does nothing other than execute the two log statements. See Minimal, Complete, and Verifiable example
– DonMag
Nov 20 '18 at 14:57
what do you want to achieve base on Switch?
– Mohammad Sadiq
Nov 20 '18 at 15:18
@MohammadSadiq I need to call 3 events by each input field type (start editing, value changed, end editing) that are used by
UIEventHandler.m
– Peter Gerhat
Nov 20 '18 at 15:41
@PeterGerhat - it's really tough for anybody to offer help when you only post partial code. For example, right now you have two
textFieldDidBegin
methods? Also, nothing to indicate wheresender.attributeID
is coming from?– DonMag
Nov 20 '18 at 16:24
@DonMag Added more details into the question. This is a question about event handling in UIKit and specifically UISwitch and UITextField. Don't want to make it too broad.
– Peter Gerhat
Nov 20 '18 at 16:39