1

Попробуйте использовать код из первого ответа в ссылке (по KAMPAI): How to use UIAlertController to replace UIActionSheet?dismissViewController обработчик завершения не называется

Однако обработчик завершения даже не вызывается в моем коде.

После нажатия обеих кнопок лист предупреждения может быть отклонен, но ничего внутри обработчика завершения не работает. Любая идея, в чем проблема? Я новичок в использовании обработчика завершения и пытаюсь найти ответы в Интернете, но у немногих есть такая же проблема, как у меня.

- (IBAction)takePhotoButtonPressed:(UIButton *)sender { 
pressedButtonTagNumber = sender.tag; 

UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 

    // Cancel button tappped 
    [self dismissViewControllerAnimated:YES completion:^{ 
    }]; 
}]]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Take a Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
    NSLog(@"!"); 
    // Take a Photo button tapped 
    [self dismissViewControllerAnimated:YES completion:^{ 
     NSLog(@"0"); // NOT CALLED 
     // Initialize UIImagePickerController 
     UIImagePickerController *takePhotoImagePickerController = [[UIImagePickerController alloc] init];   takePhotoImagePickerController.delegate = self; 
     takePhotoImagePickerController.allowsEditing = YES; 
     NSLog(@"1"); 
     // Check and assign image source 
     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 
      NSLog(@"2"); 
      UIAlertController *noCameraErrorSheet = [UIAlertController alertControllerWithTitle:@"Camera is not available" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 
      [noCameraErrorSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 
       // Cancel button tappped 
       [self dismissViewControllerAnimated:YES completion:^{ 
       }]; 
      }]]; 
     } else { 
      takePhotoImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; 
      // Present UIImagePickerController 
      [self presentViewController:takePhotoImagePickerController animated:YES completion:NULL]; 
     } 

    }]; 
}]]; 

Решение:

@ Paulw11 решение отлично работает:

1) Нет необходимости dismissViewController для UIAlertController. 2) Нельзя вызвать новый UIAlertController, если он обертывает его, отклоняя (очевидно). 3) Лучше предварительно проверить и отключить кнопку.

UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; 

[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 
}]]; 

UIAlertAction *takePhotoActionButton = [UIAlertAction actionWithTitle:@"Take Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
    [self takePhoto]; 
}]; 
UIAlertAction *uploadPhotoActionButton = [UIAlertAction actionWithTitle:@"Upload from Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
    [self uploadPhoto]; 
}]; 

// Disable take a photo button if source not available 
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 
    [takePhotoActionButton setEnabled:FALSE]; 
} 
// Disable upload a photo button if source not available 
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { 
    [uploadPhotoActionButton setEnabled:FALSE]; 
} 

[actionSheet addAction:takePhotoActionButton]; 
[actionSheet addAction:uploadPhotoActionButton]; 

// Present action sheet. 
[self presentViewController:actionSheet animated:YES completion:nil]; 
+2

Вы вызываете 'rejectViewController: animated:', чтобы отклонить UIAlertController? Если да, не делайте этого. Он автоматически отклоняется при нажатии кнопки. В обработчике действий вам просто нужно написать любой код, который вы хотите выполнить, когда выбрана кнопка действия. Например. Ваше действие «отменить» будет пустым – Paulw11

+0

Спасибо! Я тоже это нашел. Просто интересно, когда я должен использовать «[self rejectViewControllerAnimated: YES завершение:^{ }];"? Почему этот обработчик завершения не работает? –

+0

Вы используете это, когда хотите отклонить контроллер вида. Причина, по которой вы здесь не используете, заключается в том, что 'UIAlertController' уже уволился. Предположим, вам нужен тайм-аут, когда предупреждение было отменено через 5 секунд, если пользователь не выбрал вариант; вы можете запустить таймер и через 5 секунд вызвать 'rejectViewController: animated:', чтобы удалить предупреждение. – Paulw11

ответ

3

Вам не нужно вызывать dismissViewController:animated: из обработчика действий, чтобы удалить предупреждение. UIAlertController призывает это отклонить себя до вызова кода обработчика действий.

В обработчике действия вам нужно просто выполнить все, что должно быть сделано при выборе этого действия:

В этом случае:

  • В вашей отмены действия вам не нужно ничего делать
  • в ваших «сфотографировать» действия фотосъемку

Кроме того, с точкой пользовательского опыта зрения, это может быть лучше, чтобы отключить «взять фотографию» или предъявить предупреждение, как только они выберут его, а не выдать предупреждение после того, как они попытаются сделать снимок; другими словами, укажите проблему раньше, чем позже

+0

Другой вопрос по предупреждению пользователя. Теперь я всегда получал исключение: «Попытка загрузить представление контроллера представления при его освобождении не разрешена и может привести к неопределенному поведению ()». Это потому, что я положил еще один UIAlertController внутри текущего? Я немного запутался, «кто» освобождается, как указано в сообщении об ошибке. Выполните поиск в Интернете и попытайтесь удалить UIAlertController из родительского контроллера и т. Д., Теперь ничего не работает. –

+0

Да, потому что вы попытаетесь представить этот второй контроллер предупреждения первым, но первый будет уволен. Как я уже сказал, вы должны проверить, доступна ли камера перед отображением первого предупреждения. – Paulw11

+0

Решение отличное. Все работает сейчас. –

Смежные вопросы