2009-03-03 5 views
3

RootViewController 인 UITableViewController가 있습니다. XIB에는 테이블보기 만 있습니다. IB를 통해 UIActivityIndicator를 추가하고 IBOutlet을 생성했습니다. 프로그래밍 방식으로 RootViewController에 삭제 단추가있는 도구 모음을 추가했습니다. 사용자가 도구 모음의 삭제 버튼을 클릭하면 표시기를 화면 중앙에 표시하려고합니다. 아래의 방법은 데이터베이스에서 데이터를 삭제합니다. 이는 매우 빠르게 발생합니다. 나는 사용자에게 어떤 일이 일어나고 있음을 알려주고 싶다. sleep()없이 코드를 실행하면 속도가 빨라지며 표시기가 표시되지 않습니다. 하지만 어떤 이유로 든 일부 지표가 표시되지 않습니다. 나는 수면 블록을 다시 그리는 것 같아요? 내가 수면()과 마지막 두 줄을 꺼내면 표시기가 보이지만 절대로 사라지지 않습니다. 또한 창 왼쪽 상단에 표시됩니다.x 초 동안 UIActivityIndicator 표시

표시기가 최소한 1/2 초 동안 표시되도록하려면 아래 코드를 어떻게 얻습니까?

표시기를 창 중간에 정렬하는 방법은 무엇입니까?

[self.navigationController.view addSubview:activityIndicator]; 
[activityIndicator startAnimating]; 
[activityIndicator setNeedsDisplay]; 

//do something which might happen really fast 

sleep(1); //create illusion 
[activityIndicator stopAnimating]; 
[activityIndicator removeFromSuperview]; 

답변

6

회 전자는 사용자가 이벤트를 처리하고 실행 루프로 돌아올 때까지 회전을 시작하지 않습니다. 이 문제를 해결하는 방법은 실행 루프를 통해 작업을 마무리하는 것입니다. 여기

무슨 뜻인지의 예 :

- (IBAction)deleteAction:(id)sender { 
    [self.navigationController.view addSubview:activityIndicator]; 
    [activityIndicator startAnimating]; 

    // Spinner won't start spinning until we finish processing this event, so 
    // we're just going to schedule the rest of what we need to do. 

    // doDelete: will run when the main thread gets its next event. 
    [self performSelectorOnMainThread:@selector(doDelete:) 
          withObject:record 
         waitUntilDone:NO]; 

    // removeSpinner: will run in at least one second, but will wait if 
    // another event (like the doDelete: one) is in the middle of running. 
    [self performSelector:@selector(removeSpinner:) 
       withObject:activityIndicator 
       afterDelay:1.0]; 
} 
- (void)doDelete:(id)record { 
    [record delete]; // or whatever it is you need to do 
} 
- (void)removeSpinner:(UIActivityIndicator*)activityIndicator { 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 
} 

참고 : 거기에 "절전"기간 동안 다른 접촉을 처리을 중지 보장이 코드에서 아무것도 없다, 그래서 당신은 밖으로 다른 잠금 확인 어떻게 든 이벤트.

+0

굉장! 감사. 창 중간에 표시기를 표시하는 방법이 있는지 알고 있습니까? 왼쪽 상단 모서리에 중첩되어 나타납니다. – 4thSpace

+0

activityIndicator.center = CGPointMake (self.navigationController.view.frame.size.width/2, self.navigationController.view.frame.size.height/2); –

+0

브렌트에게 다시 한번 감사드립니다. 좋은 물건. – 4thSpace

0

문제는 당신이 일을하는 동안 주 실행 루프가 실행되고 있지 않다는 것입니다. 활동 표시기가 표시 되려면 기본 실행 루프가 실행되어 애니메이션을 업데이트 할 수 있어야합니다. 의도 된 동작을 얻으려면 별도의 스레드에서 데이터베이스 작업을 비동기 적으로 수행해야합니다.

+0

API가 멀티 스레딩을 허용합니까? – 4thSpace

+0

와우. 나는 "활동을 보여주기위한 지표"와 같은 것을 생각했다. * 나의 "긴"일을 끝내고 "끝내라". 하지만 왜 그런 식으로 일하지 않도록 설계 되었습니까? 이 객체의 * 전체 * 점은 "활동 표시"입니까? 으. – Bonnie

1

아담이 언급했듯이, 작업 (이 경우 삭제 작업)이 백그라운드 스레드에서 수행되지 않으면 스피너가 표시되지 않습니다. 이것은 브렌트의 초기 코드를 기반으로 작업 한 코드입니다. 백그라운드 스레드에서 작업을 수행하는 내 함수를 호출 한 다음 주 스레드를 사용하여 완료되면 회 전자를 제거하도록 수정했습니다.

- (void)removeSpinner:(id)record { 
    [activityIndicator stopAnimating]; 
    [activityIndicator removeFromSuperview]; 

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Thank You" message:@"Thanks for your feedback!" 
                           delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
    [alert show]; 
    [alert release]; 

    // return to feedings tab 
    tabBarController.selectedIndex = 0; 
} 


- (void)doFeedback:(id)record { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    int j; 
    for (int i = 0; i < 1000000000; i++) { 
     j = j + i; 
    } 
    [self performSelectorOnMainThread:@selector(removeSpinner:) withObject:nil waitUntilDone:NO]; 

    [pool release]; 
} 


- (IBAction)handleSend {   
    [self.view addSubview:activityIndicator]; 
    [activityIndicator startAnimating]; 

    // Spinner won't start spinning until we finish processing this event, so 
    // we're just going to schedule the rest of what we need to do. 
    // doFeedback: will run when the main thread gets its next event. 
    [self performSelectorInBackground:@selector(doFeedback:) withObject:nil]; 
} 
0

[self.navigationController.view addSubview : activityIndicator]; [activityIndicator startAnimating];

[self performSelector : @selector (removeSpinner :) withObject : activityIndicator afterDelay : 5.0];

관련 문제