it-swarm.com.de

Richtige Darstellung eines UIAlertControllers auf einem iPad mit iOS 8

Mit iOS 8.0 hat Apple UIAlertController eingeführt, um UIActionSheet zu ersetzen. Leider hat Apple keine Informationen hinzugefügt, wie man es präsentiert. Ich habe im Blog von hayaGeek einen Eintrag darüber gefunden, aber es scheint auf dem iPad nicht zu funktionieren. Die Ansicht ist total fehl am Platz:

Falsch platziert: Misplaced image

Richtig:enter image description here

Ich verwende den folgenden Code, um ihn auf der Schnittstelle anzuzeigen:

    let alert = UIAlertController()
    // setting buttons
    self.presentModalViewController(alert, animated: true)

Gibt es eine andere Möglichkeit, es für iPad hinzuzufügen? Oder hat Apple das iPad einfach vergessen oder noch nicht implementiert?

167
Matt3o12

Sie können eine UIAlertController aus einem Popover präsentieren, indem Sie UIPopoverPresentationController verwenden.

In Obj-C:

UIViewController *self; // code assumes you're in a view controller
UIButton *button; // the button you want to show the popup sheet from

UIAlertController *alertController;
UIAlertAction *destroyAction;
UIAlertAction *otherAction;

alertController = [UIAlertController alertControllerWithTitle:nil
                                                      message:nil
                           preferredStyle:UIAlertControllerStyleActionSheet];
destroyAction = [UIAlertAction actionWithTitle:@"Remove All Data"
                                         style:UIAlertActionStyleDestructive
                                       handler:^(UIAlertAction *action) {
                                           // do destructive stuff here
                                       }];
otherAction = [UIAlertAction actionWithTitle:@"Blah"
                                       style:UIAlertActionStyleDefault
                                     handler:^(UIAlertAction *action) {
                                         // do something here
                                     }];
// note: you can control the order buttons are shown, unlike UIActionSheet
[alertController addAction:destroyAction];
[alertController addAction:otherAction];
[alertController setModalPresentationStyle:UIModalPresentationPopover];

UIPopoverPresentationController *popPresenter = [alertController 
                                              popoverPresentationController];
popPresenter.sourceView = button;
popPresenter.sourceRect = button.bounds;
[self presentViewController:alertController animated:YES completion:nil];

Bearbeiten für Swift 4.2, obwohl es viele Blogs für dasselbe gibt, aber es kann Ihnen Zeit sparen, nach ihnen zu suchen.

 if let popoverController = yourAlert.popoverPresentationController {
                popoverController.sourceView = self.view //to set the source of your alert
                popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement.
                popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction
            }
247
Peter Hajas

Auf dem iPad wird die Warnung mit dem neuen UIPopoverPresentationController als Popover angezeigt. Sie müssen einen Ankerpunkt für die Präsentation des Popovers angeben, indem Sie entweder sourceView und sourceRect oder ein barButtonItem verwenden

  • barButtonItem 
  • sourceView
  • sourceRect

Um den Ankerpunkt anzugeben, müssen Sie einen Verweis auf den UIPopoverPresentationController des UIAlertController erhalten und eine der Eigenschaften wie folgt festlegen:

alertController.popoverPresentationController.barButtonItem = button;

beispielcode:

UIAlertAction *actionDelete = nil;
UIAlertAction *actionCancel = nil;

// create action sheet
UIAlertController *alertController = [UIAlertController
                                      alertControllerWithTitle:actionTitle message:nil
                                      preferredStyle:UIAlertControllerStyleActionSheet];

// Delete Button
actionDelete = [UIAlertAction
                actionWithTitle:NSLocalizedString(@"IDS_LABEL_DELETE", nil)
                style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {

                    // Delete
                    // [self deleteFileAtCurrentIndexPath];
                }];

// Cancel Button
actionCancel = [UIAlertAction
                actionWithTitle:NSLocalizedString(@"IDS_LABEL_CANCEL", nil)
                style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
                    // cancel
                    // Cancel code
                }];

// Add Cancel action
[alertController addAction:actionCancel];
[alertController addAction:actionDelete];

// show action sheet
alertController.popoverPresentationController.barButtonItem = button;
alertController.popoverPresentationController.sourceView = self.view;

[self presentViewController:alertController animated:YES
                 completion:nil];
98
Sabareesh

In Swift 2 möchten Sie so etwas tun, um es auf iPhone und iPad richtig anzuzeigen:

func confirmAndDelete(sender: AnyObject) {
    guard let button = sender as? UIView else {
        return
    }

    let alert = UIAlertController(title: NSLocalizedString("Delete Contact?", comment: ""), message: NSLocalizedString("This action will delete all downloaded audio files.", comment: ""), preferredStyle: .ActionSheet)
    alert.modalPresentationStyle = .Popover

    let action = UIAlertAction(title: NSLocalizedString("Delete", comment: ""), style: .Destructive) { action in
        EarPlaySDK.deleteAllResources()
    }
    let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel) { action in

    }
    alert.addAction(cancel)
    alert.addAction(action)

    if let presenter = alert.popoverPresentationController {
        presenter.sourceView = button
        presenter.sourceRect = button.bounds
    }
    presentViewController(alert, animated: true, completion: nil)
}

Wenn Sie den Presenter nicht einstellen, erhalten Sie auf dem iPad in -[UIPopoverPresentationController presentationTransitionWillBegin] eine Ausnahme mit der folgenden Meldung:

Schwerwiegende Ausnahme: NSGenericException Ihre Anwendung hat einen UIAlertController (<UIAlertController: 0x17858a00>) im Stil UIAlertControllerStyleActionSheet vorgestellt. Der modalPresentationStyle eines UIAlertControllers mit diesem Stil ist UIModalPresentationPopover. Sie müssen Standortinformationen für dieses Popover über den PopoverPresentationController des Alert-Controllers bereitstellen. Sie müssen entweder eine sourceView und eine sourceRect oder ein barButtonItem angeben. Wenn diese Informationen bei der Präsentation des Alert-Controllers nicht bekannt sind, können Sie sie in der UIPopoverPresentationControllerDelegate-Methode -prepareForPopoverPresentation angeben.

76
kviksilver

Update für Swift 3.0 und höher

    let actionSheetController: UIAlertController = UIAlertController(title: "SomeTitle", message: nil, preferredStyle: .actionSheet)

    let editAction: UIAlertAction = UIAlertAction(title: "Edit Details", style: .default) { action -> Void in

        print("Edit Details")
    }

    let deleteAction: UIAlertAction = UIAlertAction(title: "Delete Item", style: .default) { action -> Void in

        print("Delete Item")
    }

    let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in }

    actionSheetController.addAction(editAction)
    actionSheetController.addAction(deleteAction)
    actionSheetController.addAction(cancelAction)

//        present(actionSheetController, animated: true, completion: nil)   // doesn't work for iPad

    actionSheetController.popoverPresentationController?.sourceView = yourSourceViewName // works for both iPhone & iPad

    present(actionSheetController, animated: true) {
        print("option menu presented")
    }
19
iajmeri43

Hier ist eine schnelle Lösung:

NSString *text = self.contentTextView.text;
NSArray *items = @[text];

UIActivityViewController *activity = [[UIActivityViewController alloc]
                                      initWithActivityItems:items
                                      applicationActivities:nil];

activity.excludedActivityTypes = @[UIActivityTypePostToWeibo];

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    //activity.popoverPresentationController.sourceView = shareButtonBarItem;

    activity.popoverPresentationController.barButtonItem = shareButtonBarItem;

    [self presentViewController:activity animated:YES completion:nil];

}
[self presentViewController:activity animated:YES completion:nil];
7

2018 Update

Ich hatte gerade eine App aus diesem Grund zurückgewiesen und eine sehr schnelle Lösung bestand einfach darin, von einem Aktionsblatt zu einer Warnung zu wechseln.

Arbeitete einen Zauber und bestand die App Store Tester gut.

Vielleicht nicht die passende Antwort für alle, aber ich hoffe, das hilft einigen von Ihnen schnell aus einer Gurke.

5
SongBox

In Swift 4 und höher  

Ich habe eine Erweiterung angelegt 

extension UIViewController {
  public func addActionSheetForiPad(actionSheet: UIAlertController) {
    if let popoverPresentationController = actionSheet.popoverPresentationController {
      popoverPresentationController.sourceView = self.view
      popoverPresentationController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
      popoverPresentationController.permittedArrowDirections = []
    }
  }
}

Wie benutzt man: 

let actionSheetVC = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
addActionSheetForIpad(actionSheet: actionSheetVC)
present(actionSheetVC, animated: true, completion: nil)
 if let popoverController = optionMenu.popoverPresentationController {
        popoverController.sourceView = self.view
        popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
        popoverController.permittedArrowDirections = []
    }

fügen Sie einfach den obigen Code hinzu, bevor Sie Ihr UIactionsheet präsentieren

0
Captain Newt
    if let popoverController = alertController.popoverPresentationController {
        popoverController.barButtonItem = navigationItem.rightBarButtonItem
    }

für mich muss ich nur diese Zeile hinzufügen

0
Matthew Becker