2009-09-09 32 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。產生一個新的線程來完成你的加載,並在主線程上更新進度。