gpt4 book ai didi

ios - UISwitch 值更改事件在 UITextField 编辑结束之前触发

转载 作者:行者123 更新时间:2023-11-28 23:41:14 26 4
gpt4 key购买 nike

在我的应用程序中,UITableViewCell 列表中显示了许多 UISwitchUITextField

当用户开始编辑 UITextField 然后点击 UISwitch 时,事件的顺序会导致 UITextField 显示值UISwitch 因为事件处理程序没有收到 UITextField 的结束编辑事件。

如何可靠地确保 UITextFieldUIControlEventEditingDidEnd 事件在 UISwitchUIControlEventValueChanged 之前被触发?

它会导致这样的错误(文本字段中显示的开关值):

UISwitch and UITextField

步骤(应该发生什么):

1.点击UISwitch将其激活

UISwitch:startEditing:switch243
UISwitch:valueChanged:{true}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{true}

2.点击UITextField开始编辑

UITextField:startEditing:textfield455

3.点击UISwitch将其停用

UITextField:endEditing
UISwitch:startEditing:switch243
UISwitch:valueChanged:{false}
UISwitch:endEditing
UIEventHandler:saveValue:switch243:{false}

控制台日志(实际发生的情况 - UISwitch 事件在 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

实现:

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 聚合所有 UI 编辑事件:

-(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;
}

最佳答案

如果我理解正确,您遇到的问题是当文本字段是第一响应者时更改开关值时,您的文本字段的文本将更新为开关的值。

A UITextFielddidEndEditing:仅当文本字段放弃第一响应者时,事件才会发生。如果您只想确保文本字段在开关值更改时结束编辑,则应发送 endEditing:当交换机收到 UIControlEventValueChanged 时,向事件文本字段发送消息事件。

现在你如何称呼 endEditing:文本字段上的消息取决于您的类的结构。您可以在 TableView 单元格类上指定一个初始化方法,在其中传递 UITextField 的实例。对应UISwitch控制文本字段。保留对文本字段实例的弱引用,然后调用 endEditing:当开关值改变时。或者您可以简单地尝试调用 [self endEditing:YES];UITableViewCellWithSwitch 上当switchChanged:事件被触发或 [self.superview endEditing:YES]; .我更喜欢前一种解决方案而不是后者,因为后者更像是一种黑客而不是正确的解决方案。

更新:

检查您的代码后,您在问题中提到的错误原因

It leads to errors like this (value of switch displayed in text field):

是下面的一段代码:

- (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];
}

您正在调用 handleValueChangeForEditedAttribute:属性的开关值实际上只应该保存文本字段的值。在你的UIEventHandler中您正在使用 handleEndEditingForEditedAttribute 中的开关值更新数据访问对象 (DAO) 的类方法。更改您的switchChanged:方法的逻辑是这样的:

- (void)switchChanged:(UISwitch *)sender {
if (sender.on == YES) {
[self handleStartEditingForAttributeID:self.attributeID];
} else {
[self handleEndEditingForEditedAttribute];
}
}

在你的UIEventHandler类,取消注释帖子中“可能的解决方案”的注释行。这应该确保在存储新 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;
}

关于ios - UISwitch 值更改事件在 UITextField 编辑结束之前触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53395076/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com