UIButton 禁用状态不会立即改变
UIButton disabled state not changing immediately
我有一个 UIButton
设置,我想用它来告诉用户正在发生的事情,而不是只为这个实例使用加载程序。
例如 UIControlStateNormal
有:
背景绿色
标题文字白色
标题 - 点击发送
然后 UIControlStateDisabled
有:
背景白色
标题文字绿色
标题 - 发送
然后当按钮被点击时,我们将按钮更新为 enabled = NO;
。
问题
我注意到的问题是,当按钮更改为禁用(启用否)时,标题文本、颜色、背景的更改直到所有方法调用等完成后才完成,太晚了。
我在其他一些线程中读到使用 btn layoutIfNeeded
and/or btn setNeedsLayout
。这些实际上是强制更新按钮的原因,但似乎要等到所有其他 calls/methods 完成后才会发生。因此更新按钮文本等为时已晚
关于如何使按钮立即更新其状态和属性然后完成其他任务的任何想法?我已经检查以确保它在主线程和所有 updates/calls 上,所以这不是问题。
编辑
基本上当点击按钮时我们更新状态:
- (IBAction)sendFeedbackButtonPressed:(id)sender {
DebugLog(@"selected: %@",self.sendFeedbackButton.selected ? @"Yes" : @"No");
DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No");
dispatch_async(dispatch_get_main_queue(), ^{
[self shouldFeedbackButtonBeEnabled:NO];
DebugLog(@"enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No");
});
dispatch_async(dispatch_get_main_queue(), ^{
NSString *errorMessage = [self validateForm];
if (errorMessage) {
[[[UIAlertView alloc] initWithTitle:nil message:errorMessage delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Feedback Form Validation Error Ok Button", nil), nil] show];
[self shouldFeedbackButtonBeEnabled:YES];
return;
}
//TODO: send it
// Send the form values to the server here.
[self sendFeedbackToParse];
});
}
-(void)setupSendFeedbackButton {
UIColor *mainColor = [UIColor colorWithRed:41/255.0f green:128/255.0f blue:185/255.0f alpha:1];
self.sendFeedbackButton.clipsToBounds = YES;
self.sendFeedbackButton.layer.cornerRadius = 5.0f;
self.sendFeedbackButton.layer.borderWidth = 2;
self.sendFeedbackButton.layer.borderColor = mainColor.CGColor;
// Disabled State
[self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:[UIColor whiteColor]] forState:UIControlStateDisabled | UIControlStateHighlighted];
[self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button - Sending feedback disabled state", nil) forState:UIControlStateDisabled | UIControlStateHighlighted];
[self.sendFeedbackButton setTitleColor:mainColor forState:UIControlStateDisabled | UIControlStateHighlighted];
// Normal State
[self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:mainColor] forState:UIControlStateNormal];
[self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button Title", nil) forState:UIControlStateNormal];
[self.sendFeedbackButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
-(void)shouldFeedbackButtonBeEnabled:(BOOL)decision {
BOOL currentState = self.sendFeedbackButton.enabled;
if (currentState == decision) {
return;
} else {
self.sendFeedbackButton.enabled = decision;
[self.sendFeedbackButton layoutIfNeeded];
}
}
-(void)sendFeedbackToParse {
DebugLog(@"%s",__PRETTY_FUNCTION__);
DebugLog(@"button is enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No");
DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No");
// sleep(10);
// self.sendFeedbackButton.enabled = YES;
}
您检查主队列的方向是正确的,但是您的附加处理必须在 UI 有机会更新之前完成。
如果您的代码对这种方法友好,请使用两个分派块返回主队列。第一个是您的 UI-state 设置,第二个是您的剩余处理。这让 UI 状态在您的附加处理完成之前实际更新。
伪代码:
- (IBAction) handlePress:(id)sender {
dispatch_async(dispatch_get_main_queue(), ^{
// Do your state update (button disabled, etc)
});
dispatch_async(dispatch_get_main_queue(), ^{
// Do your further processing - AFTER the ui has been updated
});
}
我有一个 UIButton
设置,我想用它来告诉用户正在发生的事情,而不是只为这个实例使用加载程序。
例如 UIControlStateNormal
有:
背景绿色
标题文字白色
标题 - 点击发送
然后 UIControlStateDisabled
有:
背景白色
标题文字绿色
标题 - 发送
然后当按钮被点击时,我们将按钮更新为 enabled = NO;
。
问题
我注意到的问题是,当按钮更改为禁用(启用否)时,标题文本、颜色、背景的更改直到所有方法调用等完成后才完成,太晚了。
我在其他一些线程中读到使用 btn layoutIfNeeded
and/or btn setNeedsLayout
。这些实际上是强制更新按钮的原因,但似乎要等到所有其他 calls/methods 完成后才会发生。因此更新按钮文本等为时已晚
关于如何使按钮立即更新其状态和属性然后完成其他任务的任何想法?我已经检查以确保它在主线程和所有 updates/calls 上,所以这不是问题。
编辑
基本上当点击按钮时我们更新状态:
- (IBAction)sendFeedbackButtonPressed:(id)sender {
DebugLog(@"selected: %@",self.sendFeedbackButton.selected ? @"Yes" : @"No");
DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No");
dispatch_async(dispatch_get_main_queue(), ^{
[self shouldFeedbackButtonBeEnabled:NO];
DebugLog(@"enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No");
});
dispatch_async(dispatch_get_main_queue(), ^{
NSString *errorMessage = [self validateForm];
if (errorMessage) {
[[[UIAlertView alloc] initWithTitle:nil message:errorMessage delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Feedback Form Validation Error Ok Button", nil), nil] show];
[self shouldFeedbackButtonBeEnabled:YES];
return;
}
//TODO: send it
// Send the form values to the server here.
[self sendFeedbackToParse];
});
}
-(void)setupSendFeedbackButton {
UIColor *mainColor = [UIColor colorWithRed:41/255.0f green:128/255.0f blue:185/255.0f alpha:1];
self.sendFeedbackButton.clipsToBounds = YES;
self.sendFeedbackButton.layer.cornerRadius = 5.0f;
self.sendFeedbackButton.layer.borderWidth = 2;
self.sendFeedbackButton.layer.borderColor = mainColor.CGColor;
// Disabled State
[self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:[UIColor whiteColor]] forState:UIControlStateDisabled | UIControlStateHighlighted];
[self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button - Sending feedback disabled state", nil) forState:UIControlStateDisabled | UIControlStateHighlighted];
[self.sendFeedbackButton setTitleColor:mainColor forState:UIControlStateDisabled | UIControlStateHighlighted];
// Normal State
[self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:mainColor] forState:UIControlStateNormal];
[self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button Title", nil) forState:UIControlStateNormal];
[self.sendFeedbackButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
-(void)shouldFeedbackButtonBeEnabled:(BOOL)decision {
BOOL currentState = self.sendFeedbackButton.enabled;
if (currentState == decision) {
return;
} else {
self.sendFeedbackButton.enabled = decision;
[self.sendFeedbackButton layoutIfNeeded];
}
}
-(void)sendFeedbackToParse {
DebugLog(@"%s",__PRETTY_FUNCTION__);
DebugLog(@"button is enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No");
DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No");
// sleep(10);
// self.sendFeedbackButton.enabled = YES;
}
您检查主队列的方向是正确的,但是您的附加处理必须在 UI 有机会更新之前完成。
如果您的代码对这种方法友好,请使用两个分派块返回主队列。第一个是您的 UI-state 设置,第二个是您的剩余处理。这让 UI 状态在您的附加处理完成之前实际更新。
伪代码:
- (IBAction) handlePress:(id)sender {
dispatch_async(dispatch_get_main_queue(), ^{
// Do your state update (button disabled, etc)
});
dispatch_async(dispatch_get_main_queue(), ^{
// Do your further processing - AFTER the ui has been updated
});
}