2014-12-24 14 views
44

Ich unterhalte ein altes iOS-Projekt, das auf SDK 6.0 basiert.Wie UIAlertController verwenden, um UIActionSheet zu ersetzen?

Verfahren an diesem Projekt namens

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

verwendet wird, ein Kombinationsfeld zu zeigen. Um das Ziel zu erreichen, verwendete es UIActionSheet, das auf iOS8 veraltet ist.

ist meine Lösung dieses wie:

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

Ist das eine richtige Lösung?

Dies ist, was ich meist Besorgnis über: UIAlertController zu einem UIViewController hinzugefügt werden muss, aber ich kann den Zeiger des UIView nur bekommen, so habe ich view.nextResponder zu bekommen, was ich will, aber es ist, dass eine gute Weg?

Antwort

63

Ich habe folgenden Code verwendet, um Action-Sheet mit UIAlertViewController zu zeigen, und es funktioniert perfekt.

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

Edit:

Sie müssen hier UIViewController Objekt zu erhalten. Sie können eine globale Variable festlegen oder eine Delegate-Methode aufrufen oder die Benachrichtigung verwenden, um das View-Controller-Objekt in diesem Code abzurufen.

und letzte Zeile in obigen Code wird wie sein.

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

self.viewController ist eine globale Variable, die gesetzt werden, bevor Sie tatsächlich diese Ansicht bekommen.

Da der Ansatz, den Sie verfolgen, jetzt mit view.nextResponder. Ich habe Angst, dass es nicht funktionieren könnte.

+0

Fast die gleiche, mit Ausnahme von einem kleinen Unterschied: Ich kann nicht den Zeiger von UIViewController erhalten direkt, so habe ich auf Benutzer UIView.nextResponder statt, und ich will wissen, ob es richtig ist. –

+0

Was ist 'view' in Ihrem Code? Ist es eine Unteransicht eines View-Controllers? – Kampai

+0

Tatsächlich wird es von WebView verwendet, um ein Kombinationsfeld wie Phonegap zu öffnen. –

1

können Sie view.window.rootViewController stattdessen verwenden. Wenn Sie sich nicht um Moderator kümmern, ist es in Ordnung.

25

Ich habe ein Aktionsblatt zum Ändern des Profilbildes verwendet. Ich folgte Kampai Ansatz, nur dismissviewController Anruf entfernt, da es mir aus dem Ziel kickt wenn

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

}]]; 
10

Swift Update Abbrechen oder Fotoauswahl Ansicht drücken -

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

Während es sehr einfach aussehen mag, es ist ein unangenehmes Problem bei der Verwendung von UIAlertController. Es ist Speicherlecks anfällig. Um zu testen, ob Sie das Problem haben, setzen Sie einfach einen Haltepunkt auf die "dealloc" -Methode Ihres View-Controllers und sehen Sie, ob die Zuordnung korrekt aufgehoben wurde.

Ich wurde Lösung schon seit geraumer Zeit auf der Suche und hier ist, wie ich Alarm Controller in meiner Anwendung verwenden.

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

Dies ist nicht alles. Hier ist ein Beispiel, wie Sie es in Ihrem View-Controller verwenden. In meinem Fall ist die Tabellenansicht mit der Suche, so präsentiert Controller kann anders sein.

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