2009-09-09 33 views
3

我试图创建一个SplashView,它在后台显示Default.png和前面的UIProgressBar。但启动画面没有被更新...iPhone - 启动屏幕进度条

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

理论上看起来不错,但运行此应用程序时进度条并未更新(启动画面的方法接收到值,我可以在日志中看到它)。我也尝试加入睡眠(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 
} 

回答

3

为Default.png仅仅是一个图形,在该应用推出显示静态图像。如果你想展示进一步的进展,你将不得不在applicationDidLaunch阶段展示一切。首先在屏幕上显示你的模式“闪屏”(创建一个视图控制器,将它的view作为主窗口的子视图添加),然后在完成任何额外的加载操作后将其解除。

+0

好吧,我将创建一个UIView,添加'UIImageView',然后添加默认值。png,然后我将添加一个'UIActivityIndi​​cator'并将它显示在'mainWindow'之上。我的问题是在哪个事件中我应该关闭启动画面? – sharon 2012-02-13 14:59:16

1

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

+1

必须在主线程中更新所有UI东西。应该在单独的线程上执行什么,除了用户界面的东西。 – 2010-02-19 15:03:59

5

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

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

因此,为了实现你想要的,你必须确保drawRect被调用,比如通过将很多初始化代码推送到其他线程或计时器任务中,或者你可以通过调用强制图形在设置上下文等之后自行绘制。

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

1

据我所知,主线程是唯一可以安全执行GUI事情的主线程,它的事件循环(也就是主应用程序线程)是在你完成之后进行实际显示的那个线程称为-setNeedsDisplay。产生一个新的线程来完成你的加载,并在主线程上更新进度。