0

テキスト ラベル内に待機インジケータを使用して待機状態を表示しようとしています。

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

私の実装に何か問題がありますか、またはコードの実行中に待機インジケーターを表示するための別のコードを誰かが提供できますか? 前もって感謝します。

4

1 に答える 1

1

メイン スレッドでスリープ状態にしないでください。また、メイン スレッドから UI コンポーネントを更新しないでください。

一般的なパターンは、バックグラウンド タスクの別の実行スレッドに切り替え、更新が必要な場合はメイン スレッドに切り替えて UI を更新することです。

Grand Central DispatchNSThreadの代わりに使用している理由はありますか?


アップデート

これは、バックグラウンド スレッドに切り替えてからメイン スレッドに切り替える、非常に基本的なシナリオです。

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.
    });
});
于 2013-04-19T11:37:44.587 に答える