Yo soy el mantenimiento de un viejo iOS proyecto basado en el SDK 6.0.

Un método de este proyecto llamado

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

se utiliza para mostrar un cuadro combinado. Para lograr el objetivo, se utiliza UIActionSheet, que es obsoleto en iOS8.

Mi solución es la siguiente:

        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 que una solución adecuada?

Esto es lo que más me preocupación acerca de: UIAlertController necesita ser añadido a un UIViewController pero que sólo se puede obtener el puntero de la UIView, así que he usado la vista.nextResponder para conseguir lo que quiero, pero es que de una buena manera?

InformationsquelleAutor Don_Chen | 2014-12-24

6 Comentarios

  1. 66

    He utilizado siguiente código para mostrar la acción de la hoja utilizando UIAlertViewController y funciona perfecto.

    Swift

    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)

    Objetivo C

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

    Edición:

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

    y última línea de código anterior será igual.

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

    self.viewController es una variable global que se establecerá antes de obtener este punto de vista.

    Debido a que el enfoque está siguiendo ahora el uso de view.nextResponder. Me temo que puede que no funcione.

    • Casi el mismo, salvo por una pequeña diferencia: no puedo obtener el puntero de UIViewController directamente, por lo que he usuario UIView.nextResponder lugar, y quiero saber si es correcto.
    • ¿Qué es view en el código? Es una subvista de cualquier controlador de vista?
    • En realidad es utilizado por WebView para que aparezca un cuadro combinado, como phonegap.
    • Compruebe editado respuesta.
    • Pero tanto la configuración de una variable global o llamar a un método de delegado de significar un montón de cambios, y el proyecto mirarían raro. ¿Por qué utilizar view.nextResponder sería una mala idea? He tenido un par de pruebas y parece funcionar bien.
    • Es todo acerca de la arquitectura de la aplicación. Si usted logra obtener controlador de vista de un objeto que está muy bien. Pero cómo siempre asegúrese de que el próximo respondedor es siempre un controlador de vista.
    • Funciona bien en iOS8, pero hice algunas pruebas en iOS7 y no me funcionó 🙁
    • Tio! UIAlertController está disponible para iOS 8.0 – Y Explicar cómo se produce un error? ¿Cuál es el punto?
    • Er…yo no recuerdo que UIAlertController no es para iOS7, mi mal.
    • Gracias por tu respuesta. Es muy simple y fácil de entender. Ahorrar mi tiempo.

  2. 28

    He usado la hoja de acción para cambiar la foto de perfil. He seguido Kampai enfoque, acaba de quitar dismissviewController llamada, ya que estaba comenzando a mí de una vista al pulsar Cancelar o selección de fotos de la vista

    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. 14

    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)
  4. 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. 0

    Si bien puede parecer muy simple, hay un desagradable problema con el uso de UIAlertController. Es propensos a las fugas de memoria. Con el fin de probar si usted tiene el problema, sólo hay que poner un punto de interrupción en la vista del controlador de dealloc método y ver si se cancela la asignación correctamente.

    Yo estaba buscando una solución para bastante tiempo, y he aquí cómo utilizar una alerta controlador en mi app.

    + (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í está un ejemplo de cómo utilizarlo en su controlador de vista. En mi caso su tableview con la búsqueda, por lo que la presentación de 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
                    }
             }];
    }

Dejar respuesta

Please enter your comment!
Please enter your name here