Como implementar menus de contexto no iOS 13

Olá pessoal, meu nome é Denis, estamos desenvolvendo um serviço de análise de assinaturas para aplicativos iOS - Apphud .


Na WWDC 2019, a Apple introduziu uma nova maneira de interagir com a interface do seu aplicativo: menus de contexto . Eles se parecem com isso:



Neste artigo, consideraremos algumas das sutilezas de seu uso e aprenderemos como fazê-las.


Os menus de contexto são uma continuação lógica da tecnologia "Peek and Pop", quando o usuário pode abrir uma visualização de um elemento pressionando-o com força. Mas entre eles existem várias diferenças significativas.


  • Os menus de contexto funcionam em qualquer dispositivo executando o iOS 13. Não é necessário suporte a toque 3D do dispositivo. Portanto, em particular, eles podem ser usados ​​em todos os iPads.


  • Os botões que permitem que você interaja com o elemento aparecem imediatamente e não precisam ser deslizados para cima.



Para abrir o menu de contexto, o usuário precisa apenas segurar o dedo no item desejado ou pressionar com força (se o dispositivo suportar o 3D Touch).


Recomendações ao usar menus de contexto


As Diretrizes de interface humana da Apple recomendam que você siga estas diretrizes ao criar menus de contexto.


Projetar corretamente


Não será bom se você adicionar um menu para alguns elementos em alguns lugares e não o adicionar para elementos semelhantes em outros. Em seguida, o usuário pensará que o aplicativo não está funcionando corretamente.


Inclua apenas o necessário no menu


O menu de contexto é um ótimo local para os comandos mais usados. "Na maioria das vezes" é uma frase-chave. Não adicione tudo em uma linha.


Usar submenus


Use os submenus para facilitar a navegação do usuário. Dê aos itens de menu nomes simples e claros.


Não use mais que 1 nível de aninhamento


Apesar de os submenus facilitarem a navegação, eles podem complicá-la facilmente. A Apple não recomenda o uso de mais de um nível de aninhamento.


Coloque os itens mais usados ​​no topo


As pessoas se concentram principalmente na parte superior do menu, por isso é um pouco mais fácil navegar no aplicativo.


Usar agrupamento


Agrupe itens de menu semelhantes


Evite usar o menu de contexto e o menu de edição no mesmo item ao mesmo tempo


Eles podem entrar em conflito um com o outro, porque ambos são chamados em um longo toque.


Menu de edição do IOS


Não adicione um botão "Abrir" separado no menu


Os usuários podem abrir um item simplesmente tocando nele. Um botão adicional "Abrir" será supérfluo.


O menu de contexto mais simples para o UIView


Agora que aprendemos as regras básicas para o uso de menus de contexto, passemos à prática. Obviamente, os menus funcionam apenas no iOS 13 e superior e, para testar, você precisará do Xcode 11. Você pode fazer o download da versão beta do Xcode 11 aqui .


Você pode baixar o exemplo completamente daqui .


Vamos adicionar um menu de contexto, por exemplo, em um UIImageView , como na animação acima .


Para fazer isso, basta adicionar o objeto UIImageView ao controlador e escrever algumas linhas de código, por exemplo, no método viewDidLoad :


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

UIContextMenuInteraction , um objeto da classe UIContextMenuInteraction é UIContextMenuInteraction . O construtor exige que você especifique o delegado que será responsável pelo menu. Vamos voltar a isso um pouco mais tarde. E com o método addInteraction adicionamos nosso menu à imagem.


Agora resta implementar o protocolo UIContextMenuInteractionDelegate . Ele possui apenas um método obrigatório responsável pela criação do menu:


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

Se nil retornado neste método, o menu de contexto não será chamado. Dentro do próprio método, criamos um objeto da classe UIContextMenuConfiguration . Ao criar, passamos estes parâmetros:


  • identifier - identificador do menu.


  • previewProvider é um controlador personalizado que pode opcionalmente ser exibido em vez do item atual no menu. Vamos considerar isso um pouco mais tarde.


  • em actionProvider , passamos os itens do menu de contexto.



Os elementos em si são criados simplesmente em lugar nenhum: eles indicam o nome, um ícone opcional e um manipulador para clicar em um item de menu. Isso é tudo!


Adicionar submenu


Vamos complicar um pouco as coisas. Adicione à nossa imagem um menu com dois itens: "Salvar" e "Editar ...". Ao clicar em "Editar ...", um submenu é aberto com os itens "Girar" e "Excluir". Deve ficar assim:



Para fazer isso, reescreva o método de protocolo UIContextMenuInteractionDelegate seguinte maneira:


 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 } 

Aqui, criamos sucessivamente os botões "Salvar", "Girar" e "Excluir", adicionamos os dois últimos ao submenu "Editar ..." e agrupamos tudo no menu de contexto principal.


Adicionar menu de contexto ao UICollectionView


Vamos adicionar um menu de contexto ao UICollectionView . Com uma pressão longa na célula, o usuário verá um menu com o item "Arquivar", assim:



Adicionar um menu de contexto a um UICollectionView é simples: basta implementar o método func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? opcional func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? Protocolo UICollectionViewDelegate . Aqui está o que temos:


 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 } 

Aqui, como antes, o elemento e o próprio menu são criados. Agora, com um clique longo (forte) em uma célula, o usuário verá um menu de contexto.


Adicionar menu de contexto ao UITableView


Tudo aqui é semelhante ao UICollectionView . Você precisa implementar o método contextMenuConfigurationForRowAt do protocolo UITableViewDelegate como este:


 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 } 

Mas e se quisermos usar uma tela personalizada no menu de contexto? Por exemplo, isto:



Para fazer isso, ao criar um UIContextMenuConfiguration deve passar o UIViewController desejado para previewProvider . Aqui está um exemplo de código que implementa isso:


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

No exemplo, o PreviewViewController inicializado no storyboard e exibido no menu de contexto.


Resta adicionar o processamento de cliques a este ViewController. Para fazer isso, implemente o método willCommitMenuWithAnimator do protocolo UITableViewDelegate . O próprio manipulador será colocado dentro do animator.addCompletion :


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

Conclusão


Os menus de contexto são uma nova ferramenta poderosa para a interação do usuário com seu aplicativo. E, como você pode ver, a implementação deles é bastante simples. Mas você não deve esquecer que os métodos podem mudar até que a versão de lançamento do iOS 13 seja lançada.


Deseja implementar assinaturas no seu aplicativo iOS em 10 minutos? Integre o Apphud e:
  • Faça compras usando apenas um método;
  • rastreia automaticamente o status da assinatura de cada usuário;
  • Integre facilmente as ofertas de assinatura
  • enviar eventos de assinatura para Amplitude, Mixpanel, Slack e Telegram, levando em consideração a moeda local do usuário;
  • diminua a taxa de rotatividade de aplicativos e retorne usuários não inscritos.


O que ler?


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


All Articles