Antes de serem apresentadas durante a Conferência Mundial para Desenvolvedores de 2020 da Apple , as grades estavam entre as mais desejadas recursos a serem incluídos no SwiftUI . Até aquele ponto, muitos desenvolvedores criaram sua implementação para aproximar o UICollectionView
no SwiftUI. Em seguida, a equipe Swift apresentou oficialmente os layouts LazyVGrid
e LazyHGrid
na WWDC 2020.
Neste tutorial, examinaremos os fundamentos do layout de grade SwiftUI. Demonstraremos como criar grades com SwiftUI desenvolvendo um aplicativo de lembrete que ajuda a categorizar seus lembretes com uma data de vencimento e marcá-los como concluídos.
Vamos nos concentrar no seguinte:
- Layouts de grade em Swift
- Exemplo de layout de grade SwiftUI
- GridItems
- LazyVGrid
- LazyHGrid
- PinnedScrollableViews
Para acompanhar, você deve ter conhecimento básico de:
- SwiftUI
- pilhas
- objeto observável
- ScrollViews
Layouts de grade em Swift
Um layout de grade pode ser visto em quase todos os aplicativos da Apple. Você deve ter notado no aplicativo Fotos ou no aplicativo Agenda. Isso ajuda a acomodar mais dados vitais no mesmo espaço, dividindo as visualizações em linhas e colunas.
Dê uma olhada nos exemplos abaixo:
Exemplo de layout de grade SwiftUI
Para demonstrar como o layout de grade SwiftUI funciona, construiremos um aplicativo de lembrete. Começaremos com um projeto com todo o código da caldeira já escrito.
O aplicativo contém uma tela principal para implementar grades. Para adicionar novos lembretes ou categorias, você pode clicar no botão Adicionar no canto superior direito. O botão superior esquerdo alternará entre um layout vertical e horizontal para dar aos usuários algum controle sobre a exibição.
O aplicativo já contém um modelo para as categorias e o lembrete com o nome, a data de vencimento e um valor booleano para marcá-los como concluídos. O modelo de visualização possui métodos para adicionar mais lembretes ou atualizar o status do lembrete. O aplicativo usa dados de teste por conveniência.
Com tudo isso em mente, vamos pular para a teoria de como as grades funcionam no Swift e como elas são diferentes das listas padrão.
GridItem
Em um layout de grade no SwiftUI, cada elemento é chamado de GridItem
. Podemos personalizá-lo alterando seu tamanho, espaçamento e alinhando-o à visualização pai.
Existem três tipos de GridItem
:
- Fixo – O elemento é de tamanho fixo, não importa a orientação ou tamanho da tela do dispositivo
- Flexível -O elemento é flexível o suficiente para se redimensionar de acordo com o espaço disponível
- Adaptável -O elemento pode se adaptar ao tamanho ou orientação da tela, com largura ou altura mínimas fornecidas. Por exemplo, pode ter duas colunas no iPhone, mas no iPad, ele se adapta ao tamanho fornecido e torna-o três colunas
Esses tipos diferem de acordo com a forma como são usados, seja em uma grade vertical ou horizontal.
Começamos com uma matriz simples de itens de grade fixa com duas colunas e linhas. Agora vamos adicionar o seguinte código em style
em ReminderView
:
var items: [GridItem]=Array (repetindo:.init (.fixed (120)), contagem: 2)
Isso cria dois itens de grade de tamanho fixo de 120
em uma linha ou coluna, dependendo do que usarmos.
Você pode criar itens flexíveis da mesma forma. Esses itens ocupam o espaço disponível para preencher duas colunas ou linhas:
var items: [GridItem]=Array (repetindo:.init (.flexible ()), contagem: 2)
Da mesma forma, você pode criar itens adaptáveis:
var items: [GridItem]=Matriz (repetindo:.init (.adaptive (mínimo: 120)), contagem: 2)
Se o espaço disponível com um tamanho mínimo de 120
for suficiente para três ou quatro linhas/colunas, os itens se ajustam automaticamente.
Feito o básico, é hora de preencher esses itens em uma grade!
LazyVGrid
LazyVGrid
é uma visualização de contêiner que organiza suas visualizações filhas em uma grade que cresce verticalmente, criando itens apenas quando necessário.
A grade vertical pode ser dividida em várias colunas de acordo com sua necessidade. A API oferece flexibilidade para fixar o tamanho do elemento ou torná-lo flexível ou adaptável.
LazyVGrid
contém os seguintes parâmetros de personalização: a coluna para posicionar cada item, alinhamento na visualização, o espaçamento entre a grade e o próximo item na visualização e visualizações fixas para vincular à visualização de rolagem.
init (colunas: [GridItem], alinhamento: HorizontalAlignment=.center, espaçamento: CGFloat?=nil, pinnedViews: PinnedScrollableViews=.init (), @ViewBuilder content: ()-> Conteúdo)
Começaremos adicionando uma visualização de rolagem vertical que abrigará a grade. Em seguida, adicionaremos LazyVGrid
com as colunas como o primeiro parâmetro.
Substitua o conteúdo abaixo de style
em ReminderView
pelo seguinte:
itens
var: [GridItem] { Array (repetindo:.init (.adaptive (mínimo: 120)), contagem: 2) } var body: some View { ScrollView (.vertical, showsIndicators: false) { ForEach (viewModel.reminderCategories, id: \.id) {categoria em LazyVGrid (colunas: itens, espaçamento: 10) { ReminderListView (categoria: categoria) } .padding (.horizontal) } } }
Isso produz uma grade simples com apenas algumas linhas de código:
Passe para a orientação paisagem e a grade se adapta automaticamente a mais de duas colunas:
Agora que temos uma grade bastante vertical, é hora de modificá-la para criar uma grade horizontal legal.
LazyHGrid
A grade horizontal pode ser dividida em várias linhas. A visualização executa uma funcionalidade semelhante a LazyVGrid
.
LazyHGrid
contém parâmetros semelhantes para personalização: a linha para posicionar cada item, alinhamento na visualização, o espaçamento entre a grade e o próximo item na visualização e visualizações fixadas para vincular à visualização de rolagem.
Adicione um caso de switch em style
abaixo de ForEach ()
para distinguir entre o layout vertical e horizontal:
ScrollView (.vertical, showsIndicators: false) { ForEach (viewModel.reminderCategories, id: \.id) {categoria em mudar o estilo { case.horizontal: Texto ("o conteúdo do LazyHGrid vai aqui") case.vertical: LazyVGrid (colunas: itens, espaçamento: 10) { ReminderListView (categoria: categoria) } .padding (.horizontal) } } }
Criamos itens de tamanho fixo para o layout horizontal. Substitua a implementação antiga de itens
por:
itens
var: [GridItem] { mudar o estilo { case.vertical: return Array (repetindo:.init (.adaptive (mínimo: 120)), contagem: 2) case.horizontal: return Array (repetindo:.init (.fixed (120)), contagem: 2) } }
Agora vamos adicionar uma visualização de rolagem horizontal que abrigará a grade. Em seguida, adicione LazyHGrid
com as linhas como o primeiro parâmetro.
Substitua o conteúdo abaixo de case.horizontal
na caixa de troca pelo seguinte:
ScrollView (.horizontal, showsIndicators: false) { LazyHGrid (linhas: itens) { ReminderListView (categoria: categoria) } .padding (.vertical) }
A execução do aplicativo mostra uma lista de grades que podem ser roladas horizontalmente:
Experimente adicionar novos lembretes em diferentes categorias de urgente, importante e casual. Descobrimos que todos eles são adicionados em uma grade simples, sem cabeçalho para distingui-los. Agora precisamos de títulos para as categorias.
PinnedScrollableViews
PinnedScrollableViews
são listas de cabeçalhos que “fixam” abaixo do título de navegação durante a rolagem. Ele pode ser usado para criar um efeito aderente para o cabeçalho.
Como um exemplo prático, se você tiver muitos lembretes em uma categoria específica, seria legal ter a categoria do lembrete fixada na parte superior enquanto rola para que o usuário saiba sob qual tipo está olhando os lembretes.
Da mesma forma, você pode fixar os rodapés da visualização que ficam na parte inferior durante a rolagem.
Vamos implementar a fixação de cabeçalhos em nosso aplicativo.
Adicione o parâmetro pinnedViews
a LazyVGrid
e LazyHGrid
, que fornece a matriz de visualizações roláveis fixas. Nesse caso, seria [.sectionHeaders]
.
Agora, envolvemos rememberersView (category:)
dentro de uma Section
e criamos uma headerView
para ela. O headerView
usa o nome da categoria do lembrete como parâmetro.
função privada categoryVHeader (com cabeçalho: String)-> some View { Texto (cabeçalho) .font (.title2) .audacioso() .preenchimento() .frame (maxWidth:.infinity, maxHeight:.infinity, alinhamento:.leading) .background (RoundedRectangle (cornerRadius: 0) .fill (Color.headerBackground)) }
O código completo para nossa implementação LazyVGrid
é parecido com este:
LazyVGrid (colunas: itens, espaçamento: 10, pinnedViews: [.sectionHeaders]) { Section (header: categoryVHeader (with: category.header.name)) { RemindersView (categoria: categoria) } }
Agora, digamos que você queira algo mais notável para a grade horizontal com o cabeçalho virado 90 graus e colado no lado frontal da tela.
função privada categoryHHeader (com cabeçalho: String)-> some View { Texto (cabeçalho) .audacioso() .frame (minWidth: 70) .rotationEffect (ângulo (graus:-90)) .frame (maxWidth:.infinity, maxHeight:.infinity) .background (RoundedRectangle (cornerRadius: 0) .fill (Color.headerBackground)) }
Agora, o código para nossa implementação LazyHGrid
se parece com este:
ScrollView (.horizontal, showsIndicators: false) { LazyHGrid (rows: items, pinnedViews: [.sectionHeaders]) { Section (header: categoryHHeader (with: category.header.name)) { RemindersView (categoria: categoria) } } .padding (.vertical) }
Experimente tocar no botão de layout no canto superior esquerdo da tela para ver seus próximos lembretes em diferentes layouts de grade.
O aplicativo usa dados de teste para nossa conveniência. Para usá-lo em seu próprio trabalho, inicialize uma matriz vazia de reminderCategories
em RemindersViewModel
:
@Published var reminderCategories: [ReminderCategory]=[]
Conclusão
As grades são apropriadas para mostrar mais dados essenciais, como fotos ou arte de álbum, em menos espaço. O SwiftUI 2.0 facilita a criação de layouts de grade simples. Espero funcionalidades mais complexas no futuro.
Como uma próxima etapa, você pode tentar recriar o layout da grade do aplicativo de fotos ou criar algo semelhante ao aplicativo de lembretes para se divertir.
A postagem Compreendendo o layout da grade SwiftUI apareceu primeiro em LogRocket Blog .