2012-09-21 27 views
0

我有代碼顯示一個「加載...」視圖與活動輪,當我的應用程序加載某些屏幕。如果加載需要特別長的時間(比如4秒以上),那麼我想顯示一條額外的消息,提示「抱歉,這麼長時間,請耐心等待」。我這樣做的方式是在4秒延遲上使用NSTimer,它調用一個方法來創建一個等待視圖,然後在加載視圖上覆蓋這個新視圖,使得這些單詞不重疊。如果頁面在小於4秒內加載,則加載視圖被隱藏,等待視圖不會被觸發並且用戶繼續他或她的快樂方式。iOS - 如何在活動視圖仍然呈現動畫時顯示UIView?

當我測試屏幕加載時間超過4秒,我似乎無法得到額外的視圖來顯示。這是我的代碼:

// this method is triggered elsewhere in my code 
// right before the code to start loading a screen 
- (void)showActivityViewer 
{  
    tooLong = YES; 
    waitTimer = [NSTimer scheduledTimerWithTimeInterval:4.0 
                target:self 
               selector:@selector(createWaitAlert) 
               userInfo:nil 
                repeats:NO]; 
    [[NSRunLoop currentRunLoop] addTimer: waitTimer forMode: NSDefaultRunLoopMode]; 

    loadingView = [LoadingView createLoadingView:self.view.bounds.size.width  :self.view.bounds.size.height];  
    [self.view addSubview: loadingView]; 

    // this next line animates the activity wheel which is a subview of loadingView 
    [[[loadingView subviews] objectAtIndex:0] startAnimating]; 
} 

- (void)createWaitAlert 
{ 
    [waitTimer invalidate]; 
    if (tooLong) 
    { 
     UIView *waitView = [LoadingView createWaitView:self.view.bounds.size.width :self.view.bounds.size.height]; 
     [self.view addSubview:waitView]; 
    } 
} 

// this method gets triggered elsewhere in my code 
// when the screen has finished loading and is ready to display 
- (void)hideActivityViewer 
{ 
    tooLong = NO; 
    [[[loadingView subviews] objectAtIndex:0] stopAnimating]; 
    [loadingView removeFromSuperview]; 
    loadingView = nil; 
} 

回答

0

你確定你是從主線程執行這個嗎?試試這個:

- (void)showActivityViewer 
{  
    tooLong = YES; 

    dispatch_async(dispatch_queue_create(@"myQueue", NULL), ^{ 
     [NSThread sleepForTimeInterval:4]; 
     [self createWaitAlert]; 
    }); 

    loadingView = [LoadingView createLoadingView:self.view.bounds.size.width  :self.view.bounds.size.height];  
    [self.view addSubview: loadingView]; 

    // this next line animates the activity wheel which is a subview of loadingView 
    [[[loadingView subviews] objectAtIndex:0] startAnimating]; 
} 

- (void)createWaitAlert 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (tooLong) 
     { 
      UIView *waitView = [LoadingView createWaitView:self.view.bounds.size.width :self.view.bounds.size.height]; 
      [self.view addSubview:waitView]; 
     } 
    }); 
} 
+0

這是應該做什麼?我試過了,但結果沒有改變。順便說一句,我在createWaitAlert的最開始處添加了一條日誌打印語句,直到加載視圖消失後纔打印出來。這是否意味着它不在主線上? – JMLdev

+0

這應該確保您的添加代碼在主線程中完成。我認爲這個問題是因爲您將計時器添加到與準備您的用戶界面的繁重工作相同的運行循環中,因此它不會觸發。定時器不是一個同步機制,基本上runloop每隔一段時間就會檢查一次,看是否已經過了火災時間,然後開火。如果循環忙於做其他事情,它從不檢查。 – mprivat

+0

好的。那麼我怎樣才能把計時器放在另一個線程上,以便在主線程正在執行的「繁重工作」的同時執行呢? – JMLdev