So implementieren Sie Kontextmenüs in iOS 13

Hallo allerseits, mein Name ist Denis. Wir entwickeln einen Abonnement-Analysedienst für iOS-Anwendungen - Apphud .


Auf der WWDC 2019 stellte Apple eine neue Art der Interaktion mit der Benutzeroberfläche Ihrer Anwendung vor: Kontextmenüs . Sie sehen so aus:



In diesem Artikel werden wir einige Feinheiten ihrer Verwendung betrachten und lernen, wie man sie herstellt.


Kontextmenüs sind eine logische Fortsetzung der „Peek and Pop“ -Technologie, bei der der Benutzer eine Vorschau eines Elements öffnen kann, indem er es fest drückt. Zwischen ihnen gibt es jedoch einige signifikante Unterschiede.


  • Kontextmenüs funktionieren auf jedem Gerät mit iOS 13. Auf dem Gerät ist keine 3D-Touch-Unterstützung erforderlich. Daher können sie insbesondere auf allen iPad verwendet werden.


  • Schaltflächen, mit denen Sie mit dem Element interagieren können, werden sofort angezeigt und erfordern kein Wischen nach oben.



Um das Kontextmenü zu öffnen, muss der Benutzer nur Ihren Finger auf das gewünschte Element halten oder es fest drücken (wenn das Gerät 3D Touch unterstützt).


Empfehlungen zur Verwendung von Kontextmenüs


In den Richtlinien für die Benutzeroberfläche von Apple wird empfohlen, diese Richtlinien beim Entwerfen von Kontextmenüs zu befolgen.


Richtig gestalten


Es ist nicht gut, wenn Sie an einigen Stellen ein Menü für einige Elemente hinzufügen und an anderen Stellen kein Menü für ähnliche Elemente hinzufügen. Dann wird der Benutzer denken, dass die Anwendung nicht richtig funktioniert.


Nehmen Sie nur das Notwendige in das Menü auf


Das Kontextmenü ist ein großartiger Ort für die am häufigsten verwendeten Befehle. "Meistens" ist ein Schlüsselbegriff. Fügen Sie nicht alles hintereinander hinzu.


Verwenden Sie Untermenüs


Verwenden Sie die Untermenüs, um dem Benutzer die Navigation zu erleichtern. Geben Sie den Menüpunkten einfache und klare Namen.


Verwenden Sie nicht mehr als 1 Verschachtelungsebene


Trotz der Tatsache, dass Untermenüs die Navigation erleichtern können, können sie es leicht komplizieren. Apple empfiehlt nicht, mehr als eine Verschachtelungsstufe zu verwenden.


Legen Sie die am häufigsten verwendeten Gegenstände nach oben


Die Benutzer konzentrieren sich hauptsächlich auf den oberen Bereich des Menüs, sodass sie leichter in Ihrer Anwendung navigieren können.


Gruppierung verwenden


Gruppieren Sie ähnliche Menüpunkte


Vermeiden Sie es, das Kontextmenü und das Bearbeitungsmenü gleichzeitig für dasselbe Element zu verwenden


Sie können miteinander in Konflikt stehen, da beide in einem langen Fingertipp aufgerufen werden.


IOS-Bearbeitungsmenü


Fügen Sie im Menü keine separate Schaltfläche "Öffnen" hinzu


Benutzer können ein Element öffnen, indem sie einfach darauf tippen. Eine zusätzliche Schaltfläche „Öffnen“ ist überflüssig.


Das einfachste Kontextmenü für UIView


Nachdem wir die Grundregeln für die Verwendung von Kontextmenüs gelernt haben, können wir mit dem Üben fortfahren. Natürlich funktionieren Menüs nur unter iOS 13 und höher. Zum Testen benötigen Sie Xcode 11. Hier können Sie die Beta-Version von Xcode 11 herunterladen.


Sie können das Beispiel hier vollständig herunterladen.


UIImageView beispielsweise in einer UIImageView ein UIImageView , wie in der obigen Animation .


UIImageView Sie dazu einfach das UIImageView Objekt zum Controller hinzu und schreiben Sie mehrere Codezeilen, z. B. in die viewDidLoad Methode:


 class SingleViewController: UIViewController { @IBOutlet var imageView: UIImageView! override func viewDidLoad() { super.viewDidLoad() imageView.isUserInteractionEnabled = true let interaction = UIContextMenuInteraction(delegate: self) imageView.addInteraction(interaction) } } 

UIContextMenuInteraction wird ein Objekt der UIContextMenuInteraction Klasse UIContextMenuInteraction . Der Konstruktor verlangt, dass Sie den Delegaten angeben, der für das Menü verantwortlich ist. Kommen wir etwas später darauf zurück. Und mit der addInteraction Methode fügen wir dem Bild unser Menü hinzu.


Jetzt muss noch das UIContextMenuInteractionDelegate Protokoll implementiert werden. Es gibt nur eine obligatorische Methode, die für die Erstellung des Menüs verantwortlich ist:


 extension SingleViewController: UIContextMenuInteractionDelegate { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { actions -> UIMenu<UIAction>? in let save = UIAction(__title: "My Button", image: nil, options: []) { action in // Put button handler here } return configuration } } 

Wenn bei dieser Methode nil zurückgegeben wird, wird das Kontextmenü nicht aufgerufen. Innerhalb der Methode selbst erstellen wir ein Objekt der UIContextMenuConfiguration Klasse. Beim Erstellen übergeben wir folgende Parameter:


  • identifier - Kennung des Menüs.


  • previewProvider ist ein benutzerdefinierter Controller, der optional anstelle des aktuellen previewProvider angezeigt werden kann. Wir werden dies etwas später betrachten.


  • In actionProvider wir die Kontextmenüelemente.



Die Elemente selbst werden einfach nirgendwo erstellt: Sie geben den Namen, ein optionales Symbol und einen Handler zum Klicken auf einen Menüpunkt an. Das ist alles!


Fügen Sie ein Untermenü hinzu


Lassen Sie uns die Dinge etwas komplizieren. Fügen Sie unserem Bild ein Menü mit zwei Elementen hinzu: "Speichern" und "Bearbeiten ...". Durch Klicken auf "Bearbeiten ..." wird ein Untermenü mit den Elementen "Drehen" und "Löschen" geöffnet. Es sollte so aussehen:



UIContextMenuInteractionDelegate die Protokollmethode UIContextMenuInteractionDelegate wie folgt um:


 func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { actions -> UIMenu<UIAction>? in // Creating Save button let save = UIAction(__title: "Save", image: UIImage(systemName: "tray.and.arrow.down.fill"), options: []) { action in // Just showing some alert self.showAlert(title: action.title) } // Creating Rotate button let rotate = UIAction(__title: "Rotate", image: UIImage(systemName: "arrow.counterclockwise"), options: []) { action in self.showAlert(title: action.title) } // Creating Delete button let delete = UIAction(__title: "Delete", image: UIImage(systemName: "trash.fill"), options: .destructive) { action in self.showAlert(title: action.title) } // Creating Edit, which will open Submenu let edit = UIMenu<UIAction>.create(title: "Edit...", children: [rotate, delete]) // Creating main context menu return UIMenu<UIAction>.create(title: "Menu", children: [save, edit]) } return configuration } 

Hier erstellen wir nacheinander die Schaltflächen "Speichern", "Drehen" und "Löschen", fügen die letzten beiden zum Untermenü "Bearbeiten ..." hinzu und verpacken alles in das Hauptkontextmenü.


Fügen Sie UICollectionView Kontextmenü UICollectionView


UICollectionView wir der UICollectionView ein Kontextmenü UICollectionView . Wenn Sie lange auf die Zelle drücken, wird dem Benutzer ein Menü mit dem Eintrag "Archiv" angezeigt:



Das Hinzufügen eines Kontextmenüs zu einer UICollectionView ist einfach: Implementieren Sie einfach die optionale func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? Methode func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? UICollectionViewDelegate Protokoll. Folgendes haben wir:


 override func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { actions -> UIMenu<UIAction>? in let action = UIAction(__title: "Archive", image: UIImage(systemName: "archivebox.fill"), options: .destructive) { action in // Put button handler here } return UIMenu<UIAction>.create(title: "Menu", children: [action]) } return configuration } 

Hier werden nach wie vor das Element und das Menü selbst erstellt. Mit einem langen (starken) Klick auf eine Zelle sieht der Benutzer nun ein Kontextmenü.


Fügen Sie UITableView Kontextmenü UITableView


Alles hier ist ähnlich wie bei UICollectionView . Sie müssen die UITableViewDelegate Methode des UITableViewDelegate Protokolls wie UITableViewDelegate implementieren:


 override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { actions -> UIMenu<UIAction>? in let action = UIAction(__title: "Custom action", image: nil, options: []) { action in // Put button handler here } return UIMenu<UIAction>.create(title: "Menu", children: [action]) } return configuration } 

Aber was ist, wenn wir einen benutzerdefinierten Bildschirm im Kontextmenü verwenden möchten? Zum Beispiel:



Dazu müssen Sie beim Erstellen einer UIContextMenuConfiguration den gewünschten UIViewController an previewProvider . Hier ist ein Beispiel für Code, der dies implementiert:


 class PreviewViewController: UIViewController { static func controller() -> PreviewViewController { let storyboard = UIStoryboard(name: "Main", bundle: nil) let controller = storyboard.instantiateViewController(withIdentifier: "PreviewViewController") as! PreviewViewController return controller } } extension TableViewController: UITableViewDelegate { override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in // Return Preview View Controller here return PreviewViewController.controller() }) { _ -> UIMenu<UIAction>? in let action = UIAction(__title: "Custom action", image: nil, options: []) { action in // Put button handler here } return UIMenu<UIAction>.create(title: "Menu", children: [action]) } return configuration } } 

Im Beispiel wird PreviewViewController über das Storyboard initialisiert und im Kontextmenü angezeigt.


Es bleibt noch die Klickverarbeitung zu diesem ViewController hinzuzufügen. Implementieren Sie dazu die Methode willCommitMenuWithAnimator des UITableViewDelegate Protokolls. Der Handler selbst wird in animator.addCompletion platziert:


 override func tableView(_ tableView: UITableView, willCommitMenuWithAnimator animator: UIContextMenuInteractionCommitAnimating) { animator.addCompletion { // Put handler here } } 

Fazit


Kontextmenüs sind ein neues leistungsstarkes Tool für die Benutzerinteraktion mit Ihrer Anwendung. Und wie Sie sehen, ist ihre Implementierung recht einfach. Sie sollten jedoch nicht vergessen, dass sich die Methoden möglicherweise ändern, bis die Release-Version von iOS 13 veröffentlicht wird.


Möchten Sie in 10 Minuten Abonnements in Ihrer iOS-App implementieren? Integrieren Sie Apphud und:
  • Kaufen Sie nur mit einer Methode ein.
  • Verfolgen Sie automatisch den Status des Abonnements jedes Benutzers.
  • Abonnementangebote einfach integrieren
  • Senden Sie Abonnementereignisse an Amplitude, Mixpanel, Slack und Telegram unter Berücksichtigung der lokalen Währung des Benutzers.
  • Verringern Sie die Abwanderungsrate in Anwendungen und geben Sie nicht abonnierte Benutzer zurück.


Was zu lesen?


Source: https://habr.com/ru/post/de455854/


All Articles