Не удается получить UIActivityIndicator для отображения при вызове pushViewController в didSelectRowAtIndexPath - PullRequest
0 голосов
/ 11 января 2012

Вот мой код ...

- (void) threadStartAnimating {
    [activityIndicator startAnimating];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    activityIndicator=[[UIActivityIndicatorView alloc] init];
    [activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicator.center=[self tableView].center;
    [[self tableView] addSubview:activityIndicator];

    [NSThread detachNewThreadSelector:@selector(threadStartAnimating) toTarget:self withObject:nil];
    EventController *eventController = [[EventController alloc] init];
    [eventController setEventID:[[lineItems objectAtIndex:[indexPath row]] objectForKey:@"view_event_button_param"]];
    [activityIndicator stopAnimating];
    [[self navigationController] pushViewController:eventController animated:YES];
}

Контроллер событий содержит веб-сервис, загрузка которого занимает несколько секунд.Единственный способ показать индикатор активности - это запустить бесконечный цикл ... Я нашел несколько примеров, в которых упоминалось размещение его в отдельном потоке, но, похоже, он не работает.

Ответы [ 2 ]

5 голосов
/ 11 января 2012

Ваша проблема в том, что если вы получаете данные в viewDidLoad, то этот метод не будет вызываться до тех пор, пока не будет загружено представление, что обычно происходит в процессе первого отображения этого контроллера представления. В вашем случае это во время звонка pushViewController:animated:.

Таким образом, один из способов сделать то, что вы хотите, это поменять местами эти две строки:

[activityIndicator stopAnimating];
[[self navigationController] pushViewController:eventController animated:YES];

Но, честно говоря, я бы создал протокол с именем EventControllerDelegate, имел бы свойство слабой ссылки на id <EventControllerDelegate> в вашем EventController и затем установил бы контроллер представления, который создает EventController в качестве делегата перед Вы нажимаете это. Затем определите метод в делегате и внедрите его в свой контроллер представления, и в этом методе остановите счетчик. Затем в EventController, когда вы закончите загрузку данных, вызовите метод делегата.

Изменить: Если вы действительно хотите сделать это без определения делегата, вы можете попробовать изменить свой код на что-то вроде этого:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    activityIndicator=[[UIActivityIndicatorView alloc] init];
    [activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicator.center=[self tableView].center;
    [[self tableView] addSubview:activityIndicator];

    EventController *eventController = [[EventController alloc] init];
    [eventController setEventID:[[lineItems objectAtIndex:[indexPath row]] objectForKey:@"view_event_button_param"]];

    [activityIndicator startAnimating];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIView *v = eventController.view;

        dispatch_async(dispatch_get_main_queue(), ^{
            [activityIndicator stopAnimating];
            [[self navigationController] pushViewController:eventController animated:YES];
        });
    });
}

Он использует GCD для ясности и обычный "доступ к свойству вида" для принудительного взлома loadView / viewDidLoad ".

0 голосов
/ 11 января 2012

Вам необходимо установить размер кадра для вашего activityIndicator.

activityIndicator.frame = CGRectMake(x, y, 40, 40);
...