Закрыть actionSheet до того, как действие под его кнопкой будет завершено

Моя проблема в том, что у меня есть ActionSheet, который исчезает с экрана только тогда, когда действие под этой кнопкой завершено. Моя проблема в том, что я хочу нажать «сохранить» внутри своего листа действий, затем закрыть лист действий, а затем показать какое-то предупреждение, информирующее пользователя о необходимости дождаться завершения сохранения. В настоящее время он работает по-другому: сначала отображается лист действий, затем сохраняется сообщение ПОД листом действий, наконец, лист действий удаляется из просмотра ... поэтому пользователь не видит никаких предупреждающих сообщений.

Как закрыть actionSheet раньше, чем это сделает xcode?

Метод под sheetActionButton:

- (IBAction)saveAction:(id)sender
{
UIAlertView *alert;
alert = [[[UIAlertView alloc] initWithTitle:@"Saving photo to library\nPlease Wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
[alert show];
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.center = CGPointMake(alert.bounds.size.width / 2, alert.bounds.size.height - 50);
[indicator startAnimating];
[alert addSubview:indicator];
[indicator release];

[self saveImageToCameraRoll];

[alert dismissWithClickedButtonIndex:0 animated:YES];
}

person Nat    schedule 22.08.2011    source источник


Ответы (1)


Вы должны переместить свой метод saveImageToCameraRoll в отдельный поток или, по крайней мере, асинхронно в основном потоке. Затем вы можете закрыть предупреждение, и saveAction: сможет вернуться до его завершения.

Самый простой способ сделать это - использовать dispatch_async. Используйте dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), чтобы получить очередь для отдельного потока, или dispatch_get_main_queue() для основного потока. Убедитесь, что вы не выполняете какую-либо работу с пользовательским интерфейсом (или не используете какие-либо API-интерфейсы, которые не являются потокобезопасными) в других потоках!


Изменить: подробнее:

- (IBAction)saveAction:(id)sender {
    UIAlertView *alert;
    alert = [[[UIAlertView alloc] initWithTitle:@"Saving photo to library\nPlease Wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
    [alert show];
    UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    indicator.center = CGPointMake(alert.bounds.size.width / 2, alert.bounds.size.height - 50);
    [indicator startAnimating];
    [alert addSubview:indicator];
    [indicator release];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Save in the background
        [self saveImageToCameraRoll];
        dispatch_async(dispatch_get_main_queue(), ^{
            // Perform UI functions on the main thread!
            [alert dismissWithClickedButtonIndex:0 animated:YES];
        });
    });
}
person jtbandes    schedule 22.08.2011
comment
Я попытался изменить это по вашему совету: dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {[self saveImageToCameraRoll];}); - ›теперь он работает совершенно по-другому, но по-прежнему ошибочен: actionSheet закрывается, но после завершения работы dispatch_async отображается предупреждение o.O Почему так ..? Я хочу закрыть actionSheet, показать оповещение, сохранить действие, закрыть оповещение. Atm отклоняет actionSheet, сохраняет действие, показывает предупреждение, отклоняет предупреждение, даже несмотря на то, что в коде я написал это по-другому. - person Nat; 22.08.2011
comment
изменил его согласно некоторому руководству: dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {[self saveImageToCameraRoll]; dispatch_async (dispatch_get_main_queue (), завершение);}); где завершение является параметром метода: завершение: (void (^) (void)) завершение, и я отправляю ему NULL при вызове. Проблема, которую я описал в предыдущем комментарии, все еще существует. - person Nat; 22.08.2011
comment
Ой, извини. Вам нужно переместить [alert dismissWithClickedButtonIndex:0 animated:YES]; внутрь блока dispatch_async(dispatch_get_main_queue(), ^{ ... });. - person jtbandes; 22.08.2011
comment
Теперь это бесконечная история;) предупреждение никогда не отклоняется: / Я пытаюсь изменить код, чтобы исправить это - person Nat; 22.08.2011
comment
Понял: пришлось удалить: dispatch_async (dispatch_get_main_queue (), завершение); а теперь работает как оберег! Большое спасибо! - person Nat; 22.08.2011
comment
уже есть такой же код :) Спасибо за супер быструю и точную помощь! - person Nat; 22.08.2011