UIButton禁用状态不会立即更改

时间:2015-01-18 16:04:59

标签: ios uiview uibutton uicontrol uicontrolstate

我有一个UIButton设置,我想用它来告诉用户正在发生的事情而不是仅为这个实例使用加载器。

例如,UIControlStateNormal具有:
背景绿色
标题文字白色
标题 - 点击发送

然后UIControlStateDisabled有:
背景白色
标题文字绿色
标题 - 发送

然后,当点击该按钮时,我们将按钮更新为enabled = NO;

问题
我注意到的问题是当按钮被更改为禁用(启用NO)时,标题文本,颜色,背景的更改在完成所有方法调用等之后才会完成,所以为时已晚。

我在其他一些帖子中读到使用btn layoutIfNeeded和/或btn setNeedsLayout。这些实际上是强制按钮更新,但似乎在所有其他调用/方法完成之后才会发生。因此,更新按钮文本等为时已晚。

关于如何使按钮立即更新其状态和属性然后完成其他任务的任何想法?我已经检查过以确保它在主线程上并且所有更新/调用都不是问题。

EDIT
基本上,当点击按钮时,我们更新状态:

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

1 个答案:

答案 0 :(得分:3)

您正在检查主要队列的正确轨道,但在UI有机会更新之前,您必须完成其他处理。

如果您的代码对此方法很友好,请使用两个调度块返回主队列。第一个是您的UI状态设置,第二个是您的剩余处理。这使得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
                        });
}