Tenho cartões rolados horizontalmente, cada um com uma altura diferente. O problema é que o LazyHStack pega a altura do primeiro item, mas como alterá-la se houver um item maior? Alterar a altura no momento da rolagem também é bom. Sei que esse problema pode ser resolvido usando um HStack não preguiçoso, mas preciso de uma solução para o LazyHStack.
let items = ["Short", "Also short", "Short again", "But this is veeeery veeeery looong!"]
ScrollView(.vertical) {
VStack {
ScrollView(.horizontal) {
LazyHStack {
ForEach(0 ..< items.count) { index in
Text(items[index])
.frame(width: 150)
}
}
}
Text("Some static content here")
}
}
Uma maneira de abordar esse problema é usar um array para armazenar as alturas dos itens. O array pode ser preenchido usando um
.onGeometryChange
manipulador nos próprios itens. No entanto, você provavelmente precisará aplicar um.fixedHeight
modificador aos itens para garantir que eles usem toda a altura necessária (em particular, para garantir que textos longos não sejam truncados).Então, a altura do conteúdo pode ser determinada se o índice mínimo/máximo dos itens visíveis for conhecido.
Eu estava pensando que o modificador
onScrollTargetVisibilityChange(idType:threshold:_:)
seria ideal para determinar quais itens são visíveis (requer iOS 18). No entanto, quando tentei, às vezes eram relatados erros no console, pois o ScrollTargetVisibilityChange tentava atualizar várias vezes por quadro .Como uma abordagem alternativa, os itens podem atualizar duas variáveis de estado para
firstVisibleIndex
elastVisibleIndex
, conforme determinado pelo deslocamento de rolagem. Uma propriedade computada pode então fornecer a altura do conteúdo. A largura doScrollView
também é necessária para essa abordagem. Isso pode ser medido usando outro.onGeometryChange
modificador emScrollView
.Aqui está o exemplo atualizado para mostrar que funciona: