Действительно модальный UIAlertView в iPhone? - PullRequest
5 голосов
/ 22 февраля 2009

Мне нужно выполнить несколько проверок, которые зависят от решений пользователя (например, если утвердить покупку сверх предела расходов), и отказать в выполнении действия "выполнено", если оно не выполнено.

Однако, похоже, что невозможно выполнить по-настоящему модальное действие, как с другими языками (например, showmessage, alert () и т. Д.), И все это делегатами.

Но тогда я не знаю, что делать. Если пользователь нажимает кнопку «Готово», программа спрашивает «Вы уверены в этом?» и он говорит "отмена", поток продолжается, и представление отодвигается назад!

Как это решается в мире какао?

Ответы [ 5 ]

7 голосов
/ 22 февраля 2009

Решение состоит в том, чтобы не бороться с этим , просто разбить свою логику на две части. Если пользователь нажимает кнопку «Отмена», не выполняйте вторую часть. Если пользователь нажимает кнопку ОК / Продолжить, выполните вторую часть.

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

Используя делегаты, вы можете использовать один цикл обработки событий (вызывается через UIApplicationMain), и ни одна из этих странностей обработки событий не будет возникать.

3 голосов
/ 12 февраля 2012

Выезд: http://code.google.com/p/modal-uialertview-uiactionsheet/

С его помощью вы можете делать такие вещи, как:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil];
if ([actionSheet showModalInView:self.view] == actionSheet.destructiveButtonIndex) {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"Do you want to delete this file?" delegate:nil cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil];
    if ([alertView showModal]!= alertView.cancelButtonIndex) {
        // Delete the file
    }
}
0 голосов
/ 20 марта 2012

Я согласен с NilObject, что вы, как правило, не должны бороться с этим, и, как правило, нет. Но я использую инфраструктуру AddressBookUI, и когда я использую метод делегата,

- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier

Я бы действительно хотел предупредить пользователя, что, например, он собирается покинуть приложение, когда щелкнет адрес, который запускает приложение карты. Я использовал MapKit для создания своей собственной карты, но у меня не хватает терпения воспроизвести приложение полной карты (позволяющее пользователю получать указания от какого-то другого адреса), и прибегнул к тому, чтобы shouldPerformDefaultAction сделал свою работу запустить приложение карты, но я не могу предупредить пользователя, что он покидает приложение.

Мне бы очень хотелось, чтобы Apple представила очень базовую модель UIAlertView, а не взламывая ее. Это глупо.

0 голосов
/ 26 января 2011

Я только что столкнулся с этим вопросом как вопрос MonoTouch, и, исследуя решение, столкнулся с этим открытым вопросом.

Краткий ответ: да, это возможно. В следующем примере показано, как это сделать с помощью MonoTouch и C # на iPhone, но тот же принцип применим к Objective-C.

Для этого вы можете запустить основной цикл вручную. Мне не удалось остановить основной цикл напрямую, поэтому я вместо этого запускаю основной цикл в течение 0,5 секунды и жду, пока пользователь ответит.

Следующая функция показывает, как можно реализовать модальный запрос с помощью вышеуказанного подхода:

int WaitForClick ()
{
    int clicked = -1;
    var x = new UIAlertView ("Title", "Message",  null, "Cancel", "OK", "Perhaps");
    x.Show ();
    bool done = false;
    x.Clicked += (sender, buttonArgs) => {
        Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex);
    clicked = buttonArgs.ButtonIndex;
    };    
    while (clicked == -1){
        NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
        Console.WriteLine ("Waiting for another 0.5 seconds");
    }

    Console.WriteLine ("The user clicked {0}", clicked);
    return clicked;
}
0 голосов
/ 11 сентября 2009

Храните состояние приложения где-то еще, кроме переменных в функции. Например, в одном из моих приложений есть строка профиля, в которой указано, согласны ли они с политикой конфиденциальности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...