1

我有一个UIButton设置,我想用它来告诉用户发生了什么事情,而不是只为这个实例使用加载器。

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

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

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

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

我读了一些其他线程来使用btn layoutIfNeeded和/或btn setNeedsLayout. 这些实际上是强制更新按钮的原因,但在所有其他调用/方法完成之前似乎不会发生。因此更新按钮文本等为时已晚。

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

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

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

1 回答 1

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
                        });
}
于 2015-01-18T19:19:57.493 回答