iPhone - 启动画面带有进度条

3
我尝试创建一个SplashView,它在背景中显示Default.png,前面有一个UIProgressBar。但是启动画面没有更新...
在我的视图控制器中,我首先加载带有参数的闪屏视图,该参数表示我的初始化步骤数量,然后我通过NSTimer启动第二个线程,并在每个初始化步骤之后告诉SplashView显示新的进度值。
理论上看起来很好,但是运行此应用程序时,进度条不会更新(闪屏屏幕的方法接收到值,我可以在日志中看到)。我还尝试在其中添加usleep(10000);以给视图更新一些时间,而且也没有使用进度条,而是直接在视图上绘制并调用[self setNeedsDisplay];但都没有成功 :/
我做错了什么?
感谢您的帮助!
Tom
下面是一些代码:
SPLASHSCREEN: - (id)initWithFrame:(CGRect)frame withStepCount:(int)stepCount { if (self = [super initWithFrame:frame]) { // 初始化代码
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 { // 做一些事情,比如分配,打开数据库,创建视图,重型工作... [splashView tick]; // 这应该更新进度条...
// 做一些事情,比如分配,打开数据库,创建视图,重型工作... [splashView tick]; // 这应该更新进度条...
// 初始化完成...设置正确的视图并释放SplashView
4个回答

5
如另一个答案所述,当您的应用程序启动时,在有限的时间内会显示Default.png,并且您无法控制它。但是,如果在您的AppDelegate中创建一个显示相同Default.png的新视图,则可以从原始Default.png创建无缝过渡到您可以添加进度条的视图。
现在,您可能已经创建了一个视图或类似的内容,并且每隔一段时间更新进度条以向用户提供反馈。这里的挑战在于,您的视图仅在调用drawRect时绘制。然而,如果您从AppDelegate转到一些初始化代码到viewcontroller的viewDidLoad,而运行循环没有机会弄清楚哪些视图需要调用drawRect,那么您的视图将永远不会显示其状态栏。
因此,为了实现您想要的效果,您必须确保调用drawRect,例如通过将大量初始化代码推入其他线程或计时器任务中,或者您可以在设置上下文等之后自己调用drawRect来强制绘图。
如果选择后台任务,请确保您的初始化代码是线程安全的。

3

Default.png 只是一张图形,是在应用程序启动时显示的静态图像。如果您想显示更多的进度,您必须在 applicationDidLaunch 阶段展示所有内容。首先在那里展示您的模态“闪屏”(创建一个视图控制器,将其view添加为主窗口的子视图),并在完成任何其他加载后关闭它。


好的,我将创建一个UIView,添加UIImageView,然后将Default.png添加到其中,接着我会添加一个UIActivityIndicator并在mainWindow的顶部显示它。我的问题是在哪个事件中应该取消启动画面? - sharon

1
此外,您需要在单独的线程中更新进度条。在同一线程中更新GUI,而同时进行大量业务操作是一个不好的想法(在我看来,但我可能错了)。

1
所有UI相关的内容必须在主线程中更新。应该放在单独的线程中的是除了UI相关的其他所有内容。 - Oscar Gomez

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接