ios objective-c uialertcontroller uiactionsheet

ios - ¿Cómo usar UIAlertController para reemplazar UIActionSheet?



objective-c (6)

He usado el siguiente código para mostrar la hoja de acción usando UIAlertViewController y funciona perfecto.

- (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]; }

Editar:

Necesita obtener el objeto UIViewController aquí. Puede establecer una variable global o llamar a un método delegado, o puede usar la notificación para obtener el objeto controlador de vista en este código.

y la última línea en el código anterior será similar.

[self.viewController presentViewController:actionSheet animated:YES completion:nil];

self.viewController es una variable global que se establecerá antes de que realmente obtengas esta vista.

Porque el enfoque que estás siguiendo ahora usa view.nextResponder . Me temo que puede no funcionar.

Estoy manteniendo un viejo proyecto de iOS basado en SDK 6.0.

Un método en este proyecto llamado

-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options

se usa para mostrar un cuadro combinado. Para lograr el objetivo, utilizó UIActionSheet, que está en desuso en iOS8.

Mi solución es así:

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''s the right way if ([view.nextResponder isKindOfClass:UIViewController.class]) { UIViewController* vc = (UIViewController*)view.nextResponder; [vc presentViewController:alertController animated:YES completion:nil]; }

¿Es esa una solución adecuada?

Esto es lo que más me preocupa : UIAlertController necesita ser agregado a un UIViewController pero solo puedo obtener el puntero de UIView, así que usé view.nextResponder para obtener lo que quiero, ¿pero es una buena manera?


He usado una hoja de acción para cambiar la imagen de perfil. Seguí el enfoque de Kampai, simplemente eliminé la llamada de destello del control ya que me estaba sacando de una vista al presionar Cancelar o seleccionar la vista de la foto

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]; }]];


Puede usar view.window.rootViewController en view.window.rootViewController lugar. Si no te importa el presentador, está bien.


Si bien puede parecer muy simple, hay un problema desagradable con el uso de UIAlertController . Es una pérdida de memoria propensa. Para probar si tiene el problema, simplemente coloque un punto de interrupción en el método dealloc su controlador de dealloc y vea si está desasignado correctamente.

Estaba buscando una solución por bastante tiempo y así es como uso un controlador de alerta en mi aplicación.

+ (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]; }

Esto no es todo. Aquí hay un ejemplo de cómo lo usa en su controlador de vista. En mi caso, es una tableview con búsqueda, por lo que la presentación del controlador puede ser diferente.

- (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 } }]; }


Swift actualización -

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)


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)