2012-09-21 2 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

이것은 추가 코드가 주 스레드에서 완료되었는지 확인해야합니다. UI를 준비하는 무거운 짐을 싣는 작업을 수행하는 루프와 동일한 실행 루프에 타이머를 추가했기 때문에 문제가 발생했다고 생각합니다. 타이머는 sync'ed 메커니즘이 아니며, 기본적으로 runloop은 화재 시간이 경과했는지 확인하기 위해 주기적으로 점검합니다. 루프가 다른 작업을하기 위해 바쁜 경우에는 절대로 확인하지 않습니다. – mprivat

+0

아 좋아요. 그렇다면 어떻게 다른 스레드에 타이머를 두어 주 스레드에서 수행중인 "무거워 짐"과 동시에 실행되도록할까요? – JMLdev

관련 문제