3

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

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

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

我究竟做错了什么?

谢谢你的帮助!

汤姆

这是一些代码:

启动画面:
- (id)initWithFrame:(CGRect)frame withStepCount:(int)stepCount {
    if (self = [super initWithFrame:frame]) {
        // 初始化代码

        背景 = [[UIImageView alloc] initWithFrame: [self bounds]];
        [背景setImage: [UIImage imageWithContentsOfFile: [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"Default.png"]]];
        [自我添加子视图:背景];

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

        stepValue = 1.0f / (float)stepCount;

        [自我 addSubview:progressView];
    }
    回归自我;
}

-(无效)勾选{
    值 += 步值;
    [progressView 设置进度:值];
}



浏览器:

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

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

        NSTimer* 延迟定时器;
        delayTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 目标:自我选择器:@selector(finishInitialization) userInfo:nil repeats:NO];
    }
    回归自我;
}

- (void)finishInitialization {
    // 做一些事情,比如分配、打开数据库、创建视图、繁重的事情......
    [splashView 勾选]; // 这应该更新进度条...

    // 做一些事情,比如分配、打开数据库、创建视图、繁重的事情......
    [splashView 勾选]; // 这应该更新进度条...

    // 初始化完成...设置正确的视图并释放 SplashView
}
4

4 回答 4

5

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

现在,大概您已经创建了一个视图或类似的视图,并且您经常更新进度条以便给用户一些反馈。这里的挑战是您的视图仅在被调用执行 drawRect 时才被绘制。但是,如果您从 AppDelegate 转到一些初始化代码到视图控制器的 viewDidLoad,而运行循环没有机会确定哪些视图需要调用 drawRect,那么您的视图将永远不会显示其状态栏。

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

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

于 2009-09-09T04:36:58.247 回答
3

Default.png 只是一个图形,是应用程序启动时显示的静态图像。如果你想展示进一步的进步,你必须展示applicationDidLaunch阶段的一切。首先在此处显示您的模态“启动画面”(创建一个视图控制器,将其添加view为主窗口的子视图),并在您完成所需的任何额外加载后将其关闭。

于 2009-09-09T03:59:18.593 回答
1

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

于 2009-09-09T04:28:03.833 回答
1

据我所知,主线程是唯一可以安全地做 GUI 事情的线程,它的事件循环(即主应用程序线程)是在你调用-setNeedsDisplay. 生成一个新线程来进行加载,并更新主线程的进度。

于 2009-09-09T04:56:37.613 回答