Quero usar o novo modificador contextMenu com 'visualização', ao mesmo tempo que oferece suporte ao iOS15. Estou tentando criar um ViewModifier
para isso para poder fazer a verificação de disponibilidade lá, mas estou tendo dificuldades para entender a sintaxe dos parâmetros 'genéricos' aqui.
Isso é o que eu estava tentando:
struct CompatiblityContextMenuModifier: ViewModifier {
@ViewBuilder let actionsList: Group<Any>
@ViewBuilder let actionsPreview: any View
func body(content: Content) -> some View {
if #available(iOS 16.0, *){
content
.contextMenu(menuItems: actionsList, preview: actionsPreview)
} else {
content
.contextMenu(menuItems: actionsList)
}
}
}
Mas o compilador reclama:
Cannot convert value of type 'any View' to expected argument type '() -> P'
Cannot convert value of type 'Group<Any>' to expected argument type '() -> M'
Generic parameter 'M' could not be inferred
Generic parameter 'P' could not be inferred
Eu sei que preciso especificar um 'tipo' diferente para actionsList e actionPreview, mas o que seria exatamente?
Esta é a aparência da chamada de função para contextMenu:
func contextMenu<M, P>(
@ViewBuilder menuItems: () -> M,
@ViewBuilder preview: () -> P
) -> some View where M : View, P : View
O que exatamente é "() -> M" e "() -> P"
O seguinte é o que tenho até agora. Para incorporar
View
como argumentoViewModifier
, você precisa de uma técnica específica. Este tópico foi útil. Neste caso, você tem que incorporar dois conjuntos deView
, que de alguma forma consegui por tentativa e erro.A seguir está como eu testo para iOS 16.
View e Group que não são diretamente compatíveis com os tipos esperados pelo contextMenu. Além disso, o modificador contextMenu do SwiftUI não aceita um Group como seu parâmetro menuItems. Em vez disso, espera um fechamento que retorne alguma View.
Para corrigir o problema e criar um ViewModifier genérico, você pode usar o atributo @ViewBuilder para o fechamento de ações e usar um espaço reservado de tipo genérico para a visualização que esteja em conformidade com View. Veja como você pode fazer isso:
}
Você pode fornecer um fechamento para os itens de menu e, opcionalmente, para a visualização quando estiver no iOS 16 ou posterior:
}
Dessa forma, você fornece um encerramento que retorna os itens de menu e, condicionalmente, um encerramento que retorna o conteúdo de visualização. Isso deve ser compilado corretamente e fornecer o comportamento desejado no iOS 15 e no iOS 16.