Objective-C,如何显示确定的进度条?

时间:2012-06-04 23:04:47

标签: objective-c methods progress-bar

我想在我的应用中显示进度条是确定的而不是不确定的。当它设置为确定时它不起作用(对于不确定的工作正常)。虽然他们没有工作,我read someother的回答{{3}}。任何帮助将不胜感激 - 谢谢!

@interface AppDelegate : NSObject <NSApplicationDelegate> {

    IBOutlet NSProgressIndicator *showProgress;

}

- (IBAction)someMethod:(id)sender {

    [showProgress setUsesThreadedAnimation:YES];   // This works
    [showProgress startAnimation:self];            // This works
    [showProgress setDoubleValue:(0.1)];           // This does not work
    [showProgress setIndeterminate:NO];            // This does not work

    [self doSomething];
    [self doSomethingElse];
    [self doSomethingMore];
    ....

    [barProgress setDoubleValue:(1.0)];            // This does not work
    [barProgress stopAnimation:self];              // This works

}

更新了代码[working]:

- (IBAction)someMethod:(id)sender {

    [showProgress setUsesThreadedAnimation:YES];
    [showProgress startAnimation:self];
    [showProgress setIndeterminate:NO];

    [showProgress setDoubleValue:(0.1)];
    [showProgress startAnimation:nil];

    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{

        for (NSUInteger i = 0; i < 1; i++) {

            dispatch_async(dispatch_get_main_queue(), ^{
                [barProgress incrementBy:10.0];
            });
        }

    [self doSomething];

            [showProgress incrementBy:...];

        dispatch_async(dispatch_get_main_queue(), ^{

            [showProgress stopAnimation:nil];

        });
    });

    [showProgress setDoubleValue:(1.0)];
}

1 个答案:

答案 0 :(得分:4)

您的doSomething方法阻塞了主线程,导致运行循环不循环,从而导致UI重绘被阻止。修复是在后台队列上的doSomething中进行长时间运行的工作,定期回调主队列以更新进度条。

我不知道你的doSomething方法做了什么,但为了便于解释,我们假设它运行一个包含100步的for循环。你实现它是这样的:

- (void)doSomething
{
    [showProgress startAnimation:nil];
    dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(backgroundQueue, ^{
        for (NSUInteger i = 0; i < 100; i++) {
            // Do whatever it is you need to do

            dispatch_async(dispatch_get_main_queue(), ^{
                [showProgress incrementBy:1.0];
            });
        }
        // Done with long running task
        dispatch_async(dispatch_get_main_queue(), ^{
            [showProgress stopAnimation:nil];
        });
    });
}

请记住,您仍然需要将进度指示器设置为确定,初始化其值并设置适当的minValue和maxValue。

如果您必须在主线程上的doSomething中进行工作,则可以在每个运行循环周期中安排小块的工作,或者定期手动旋转运行循环如果你能使用它,那么Grand Central Dispatch(GCD)将是我的第一选择。