Как использовать UIAlertController для замены UIActionSheet?
Я поддерживаю старый проект iOS, основанный на SDK 6.0.
Метод этого проекта под названием
-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options
используется для отображения комбинированного поля. Для достижения этой цели он использовал UIActionSheet, который устарел на iOS8.
Мое решение таково:
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8) {
UIAlertController* alertController = [UIAlertController
alertControllerWithTitle:@"title"
message:@"message"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* item = [UIAlertAction actionWithTitle:@"item"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
//do something here
//inform the selection to the WebView
...
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
[alertController addAction:item];
[alertController addAction:cancelAction];
//I am not sure whether it the right way
if ([view.nextResponder isKindOfClass:UIViewController.class]) {
UIViewController* vc = (UIViewController*)view.nextResponder;
[vc presentViewController:alertController animated:YES completion:nil];
}
Это правильное решение?
В основном это проблема : UIAlertController необходимо добавить в UIViewController, но я могу получить только указатель UIView, поэтому я использовал view.nextResponder, чтобы получить то, что хочу, но это хороший способ?
Ответы
Ответ 1
Я использовал следующий код, чтобы показать лист действий с помощью UIAlertViewController
и он отлично работает.
стриж
let alert = UIAlertController(title: "Action Title", message: "Action Message", preferredStyle: .actionSheet)
let action = UIAlertAction(title: "Item", style: .default) {
UIAlertAction in
// Write your code here
}
alert.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
UIAlertAction in
// It will dismiss action sheet
}
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
Цель С
- (IBAction)buttonClicked:(id)sender {
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Action Sheet" message:@"Using the alert controller" preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// OK button tapped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}]];
// Present action sheet.
[self presentViewController:actionSheet animated:YES completion:nil];
}
Редактировать:
Вам нужно получить объект UIViewController
здесь. Вы можете установить глобальную переменную или вызвать метод делегата, или вы можете использовать уведомление, чтобы получить объект контроллера представления в этом коде.
и последняя строка в приведенном выше коде будет выглядеть так.
[self.viewController presentViewController:actionSheet animated:YES completion:nil];
self.viewController
- это глобальная переменная, которая будет установлена до того, как вы получите это представление.
Потому что подход, view.nextResponder
вы придерживаетесь, теперь использует view.nextResponder
. Боюсь, что это может не сработать.
Ответ 2
Я использовал лист действий для изменения изображения профиля. Я последовал за Кампайским подходом, просто удалил вызов rejectviewController, так как он выбил меня из вида, когда нажимал кнопку Отмена или выбор фотографий
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Cancel button tappped do nothing.
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Take photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// take photo button tapped.
[self takePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Choose photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// choose photo button tapped.
[self choosePhoto];
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete Photo" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// Distructive button tapped.
[self deletePhoto];
}]];
Ответ 3
Свифт обновление -
let actionSheet = UIAlertController.init(title: "Please choose a source type", message: nil, preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction.init(title: "Take Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.openCamera()
}))
actionSheet.addAction(UIAlertAction.init(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { (action) in
self.showPhotoLibrary()
}))
actionSheet.addAction(UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) in
// self.dismissViewControllerAnimated(true, completion: nil) is not needed, this is handled automatically,
//Plus whatever method you define here, gets called,
//If you tap outside the UIAlertController action buttons area, then also this handler gets called.
}))
//Present the controller
self.present(actionSheet, animated: true, completion: nil)
Ответ 4
Swift 4
let alert = UIAlertController(title: "Select One", message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Export", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Export wordlist
}))
alert.addAction(UIAlertAction(title: "Import", style: UIAlertActionStyle.default, handler: { (action) in
// TODO: Import wordlist
}))
self.present(alert, animated: true, completion: nil)
Ответ 5
Вместо этого вы можете использовать view.window.rootViewController
. Если вас не волнует презентатор, все в порядке.
Ответ 6
Хотя это может выглядеть очень просто, есть проблема с использованием UIAlertController
. Это утечки памяти склонны. Чтобы проверить, есть ли у вас проблема, просто установите точку останова в вашем методе dealloc
контроллера представления и посмотрите, правильно ли он освобожден.
Я долго искал решение, и вот как я использую контроллер предупреждений в своем приложении.
+ (void)alertWithPresenting:(UIViewController *)presenting title:(NSString *)title
text:(NSString *)text buttons:(NSArray *)buttons
handler:(void (^)(UIAlertAction *action, NSUInteger index))handler
{
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:title message:text
preferredStyle:UIAlertControllerStyleAlert];
__weak __typeof(alert) weakAlert = alert;
for (NSString *title in buttons) {
UIAlertActionStyle style = UIAlertActionStyleDefault;
if ([title isEqualToString:[L10n cancelButton]])
style = UIAlertActionStyleCancel;
else if ([title isEqualToString:[L10n deleteButton]])
style = UIAlertActionStyleDestructive;
else if ([title isEqualToString:[L10n archiveButton]])
style = UIAlertActionStyleDestructive;
UIAlertAction *action = [UIAlertAction actionWithTitle:title style:style handler:^(UIAlertAction *action) {
if (handler != nil)
handler(action, [buttons indexOfObject:action.title]);
[weakAlert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:action];
}
[presenting presentViewController:alert animated:YES completion:nil];
}
Это еще не все. Вот пример того, как вы используете его в вашем контроллере представления. В моем случае это tableview
с поиском, поэтому представление контроллера может отличаться.
- (void) deleteCases:(NSArray *)selectedRows
{
NSString *text = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.text",
@"Localizable", [NSBundle mainBundle],
@"Deleted cases cannot be restored. Continue with delete?",
@"Delete alert text");
NSString *title = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.title",
@"Localizable", [NSBundle mainBundle],
@"Delete cases", @"Detete alert title");
UIViewController *presenting = self.searchController.active ? self.searchController : self;
__weak __typeof(presenting) weakPresenting = presenting;
__weak __typeof(self) weakSelf = self;
[YourClassName alertWithPresenting:weakPresenting title:title text:text
buttons:@[[L10n deleteButton], [L10n cancelButton]]
handler:^(UIAlertAction *action, NSUInteger index)
{
if (action.style == UIAlertActionStyleDestructive) {
__typeof(weakSelf) strongSelf = weakSelf;
// Perform your actions using @strongSelf
}
}];
}