iPhone - 带进度条的启动画面

时间:2009-09-09 03:42:06

标签: iphone splash-screen uiprogressview

我尝试创建一个SplashView,它在后台显示Default.png,在前面显示UIProgressBar。但是启动画面没有更新......

在我的视图控制器中,我首先使用参数加载启动视图,我的初始化步数是多少,然后我通过NSTimer启动第二个线程,在每个初始化步骤之后,我告诉SplashView显示新的进度值。

理论上一切看起来都不错,但是在运行这个应用程序时,进度条没有被更新(启动画面的方法接收值,我可以在日志中看到它)。我也尝试添加usleep(10000);在两者之间给视图更新一点时间,而不是使用我直接在视图上绘制的进度条并调用[self setNeedsDisplay];但都没有用:/

我做错了什么?

感谢您的帮助!

汤姆

以下是一些代码:

SPLASHSCREEN:
- (id)initWithFrame:(CGRect)frame withStepCount:(int)stepCount {
    if (self = [super initWithFrame:frame]) {
        // Initialization code

        background = [[UIImageView alloc] initWithFrame: [self bounds]];
        [background setImage: [UIImage imageWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"Default.png"]]];
        [self addSubview: background];

        progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
        [progressView setFrame:CGRectMake(60.0f, 222.0f, 200.0f, 20.0f)];
        [progressView setProgress: 0.0f];

        stepValue = 1.0f / (float)stepCount;

        [self addSubview:progressView];
    }
    return self;
}

- (void)tick {
    value += stepValue;
    [progressView setProgress: value];
}



VIEWCONTROLLER:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {

        splashView = [[SplashView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 480.0f) withStepCount:9];
        [self setView: splashView];

        NSTimer* delayTimer;
        delayTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(finishInitialization) userInfo:nil repeats:NO];
    }
    return self;
}

- (void)finishInitialization {
    // do some stuff, like allocation, opening a db, creating views, heavy stuff...
    [splashView tick]; // this should update the progress bar...

    // do some stuff, like allocation, opening a db, creating views, heavy stuff...
    [splashView tick]; // this should update the progress bar...

    // init done... set the right view and release the SplashView
}

4 个答案:

答案 0 :(得分:5)

正如另一个答案中所提到的,在一段有限的时间内,当您的应用程序正在启动时,会显示Default.png并且您无法控制它。但是,如果在AppDelegate中创建了一个显示相同Default.png的新视图,则可以创建从原始Default.png到可以添加进度条的视图的无缝转换。

现在,大概是,您创建了一个视图或类似视图,并且每隔一段时间就会更新一个进度条,以便为用户提供一些反馈。这里的挑战是,只有在调用drawRect时才会绘制视图。但是,如果您从AppDelegate转到某个初始化代码到viewcontroller的viewDidLoad,而没有运行循环有机会找出需要调用drawRect的视图,那么您的视图将永远不会显示其状态栏。

因此,为了实现您想要的目标,您必须确保调用drawRect,例如将大量初始化代码推送到其他线程或计时器任务中,或者您可以通过调用drawRect来强制绘制在设置上下文之后,你自己。

如果您使用后台任务,请确保您的初始化代码是线程安全的。

答案 1 :(得分:3)

Default.png只是一个图形,是应用程序启动时显示的静态图像。如果您想显示进一步的进展,则必须在applicationDidLaunch阶段显示所有内容。首先在那里显示模态“启动画面”(创建一个视图控制器,将其view添加为主窗口的子视图),并在完成所需的其他加载时将其解除。

答案 2 :(得分:1)

此外,您需要在单独的线程中更新进度条。在许多业务正在进行的同一个线程中更新GUI(在我看来,但我可能是错的)是一个坏主意。

答案 3 :(得分:1)

据我所知,主线程是唯一一个可以安全地执行GUI操作的线程,它的事件循环(即主应用程序线程)是在你调用之后进行实际显示的线程。 -setNeedsDisplay。产生一个新线程来进行加载,并更新主线程的进度。