退出调用方法之前不会更新显示

时间:2013-04-19 10:19:54

标签: ios objective-c iphone ios6

我正在尝试在文本标签中显示等待指示器的等待状态。

-(void)progressTask {

    while (taskInProgress == YES) {

        if (progressStepChanged == YES) {
            progressStepChanged = NO;
            switch (progressStep) {
                case E_PROGRESS_NONE:
                    break;

                case E_PROGRESS_WAIT:
                    HUD.mode = ProgressHUDModeIndeterminate;
                    HUD.labelText = @"Please Wait";
                    HUD.detailsLabelText = @"Transaction in Progress";
                    HUD.labelTextColor = [UIColor whiteColor];
                    HUD.detailsLabelTextColor = [UIColor whiteColor];
                    HUD.dimBackground = YES;
                    break;

                case E_PROGRESS_DECLINED:
                    HUD.mode = ProgressHUDModeCustomView;
                    HUD.labelText = @"Transaction Result";
                    HUD.detailsLabelText = @"Declined";
                    HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Cross.png"]];
                    HUD.labelTextColor = [UIColor blueColor];
                    HUD.detailsLabelTextColor = [UIColor redColor];
                    HUD.dimBackground = YES;
                    break;

                case E_PROGRESS_COMM_LOST:
                    HUD.dimBackground = YES;
                    break;

                case E_PROGRESS_APPROVED:
                    HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
                    HUD.mode = ProgressHUDModeCustomView;
                    HUD.labelText = @"Transaction Result";
                    HUD.detailsLabelText = @"Approved";
                    HUD.labelTextColor = [UIColor blueColor];
                    HUD.detailsLabelTextColor = [UIColor greenColor];
                    HUD.dimBackground = YES;
                    break;

                default:
                    break;
            }
        }
        usleep(100);
    }
}

-(void)startProgressManager:(UIViewController*)viewController {
    if (HUD == nil) {
        HUD = [[ProgressHUD alloc] initWithView:viewController.navigationController.view];
        [viewController.navigationController.view addSubview:HUD];
        HUD.delegate = self;
    }
    [HUD showWhileExecuting:@selector(progressTask) onTarget:self withObject:nil animated:YES];
}

“progressTask”中的每个参数都有一个观察者。 ProgressHUD类负责在信息文本中创建等待指示符。 “progressTask”作为后台任务启动:

-(void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {
    methodForExecution = method;
    targetForExecution = target;
    objectForExecution = object;    
    // Launch execution in new thread
    self.taskInProgress = YES;
    [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
    // Show HUD view
    [self show:animated];
}


-(void)show:(BOOL)animated {

    if (animated && animationType == ProgressHUDAnimationZoomIn) {
        self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));
    } else if (animated && animationType == ProgressHUDAnimationZoomOut) {
        self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));
    }
    self.showStarted = [NSDate date];
    // Fade in
    if (animated) {
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.30];
        self.alpha = 1.0f;
        if (animationType == ProgressHUDAnimationZoomIn || animationType == ProgressHUDAnimationZoomOut){
            self.transform = rotationTransform;
        }
        [UIView commitAnimations];
        [self setNeedsDisplay];
    }
    else {
        self.alpha = 1.0f;
    }
}

问题是当我从ViewController类调用“startProgressManager”时,等待指示器仅在退出方法后显示(在sleep(3)之后)。

-(IBAction)recallBtnPress:(id)sender {
    progressManager = [ProgressManager new];
    [progressManager startProgressManager:self];
    progressManager.progressStep = E_PROGRESS_WAIT;
    sleep(3);
}

我的实现中是否有问题,或者在代码运行时是否有人为等待指示器显示提供了另一个代码。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

不要在主线程上休眠,也不要在主线程上更新UI组件。

一般模式是切换到后台任务的单独执行线程,当需要更新时切换到主线程以更新UI。

出于好奇,您使用NSThread代替Grand Central Dispatch是有原因的吗?


<强>更新

这是切换到后台线程,然后切换到主线程的非常基本的场景。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // THIS CODE RUNS IN THE BACKGROUND

    // Your data crunching. You can call methods on self, if it's thread safe.

    // AFTER PROCESSING
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        // SWITCH BACK TO THE MAIN THREAD

        // Update the UI.
    });
});