Este código mostra uma visualização no estilo cover-flow onde você pode rolar pelas imagens em uma Scroll View, enquanto as imagens em si vêm de uma matriz. O espaçamento é -100 para permitir que as outras imagens que não estão no meio da tela apareçam atrás da imagem atual. Embora isso esteja funcionando bem no lado esquerdo, no lado direito da imagem atual, as outras imagens na ScrollView estão se cruzando:
(o avião de papel está no meio e os símbolos de download estão na frente dele)
Usando zIndex, gostaria de atualizar dinamicamente a visualização quando o usuário estiver rolando pela galeria. Tentei usar GeometryReader com @State var selectedItemInd, mas isso não funcionou muito bem para mim, pois a visualização não foi atualizada. Acredito que toda vez que o usuário rolar, eu não precisaria apenas saber qual item está na posição do meio, mas também onde todos os outros itens estão.
import SwiftUI
import MusicKit
struct ContentView: View {
#if false
let images = ["Ghost - Single", "Burre - Single", "Butterfly 3001", "Tension (Deluxe)", "Shreya Ghoshal_ Best of Me", "Life - EP", "Liebeskummer lohnt sich nicht"]
#else
let images = ["externaldrive.fill.badge.checkmark", "square.and.arrow.up.fill", "square.and.arrow.up.circle", "folder.circle", "paperplane.fill", "square.and.arrow.down", "square.and.arrow.down.fill", "doc.badge.gearshape", "square.and.arrow.up.on.square.fill"]
let colours = [Color.red, Color.blue, Color.green, Color.yellow, Color.orange, Color.purple, Color.pink, Color.cyan, Color.indigo]
#endif
var itemWidthHeight: CGFloat = CGFloat(200)
@StateObject var albums = MusicStorage.shared
@StateObject var authorizationObject = AuthorizationHandler.shared
// @State var selectedItemInd: Int = 0
var body: some View {
VStack{
GeometryReader { geo in
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: -100) {
ForEach(0..<images.count) { s in
Image(systemName: images[s])
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: itemWidthHeight, height: itemWidthHeight)
.background(colours[s])
.visualEffect { effect, proxy in
let frame = proxy.frame(in: .scrollView(axis: .horizontal))
let distance = frame.minX
// print(distance)
return effect
//only rotate at left or right swipe, not both at once
// distance to left is negative, distance to right is positive value
.rotation3DEffect(Angle(degrees: distance < 0 ? min(-distance * 0.3, 40) : 0), axis: (x: 0.0, y: 1.0, z: 0.0))
.rotation3DEffect(Angle(degrees: distance > 0 ? max(-distance * 0.3, -40) : 0), axis: (x: 0.0, y: 1.0, z: 0.0))
}
// .frame(width: itemWidthHeight, height: itemWidthHeight, alignment: .center)
}
}
.scrollTargetLayout()
}
.frame(width: geo.size.width, height: geo.size.height, alignment: .center)
.contentMargins((geo.size.width / 2) - itemWidthHeight / 2) // scroll view item should be in middle position
.scrollTargetBehavior(.viewAligned(limitBehavior: .automatic))
}
}
.onAppear() {
albums.loadAlbums()
}
// Sheet is presented if authorization failed (init)
.sheet(isPresented: $authorizationObject.isSheetPresented) {
AuthorizationSheet(musicAuthorizationStatus: $authorizationObject.isAuthorizedForMusicKit)
.interactiveDismissDisabled()
}
}
}
#Preview {
ContentView()
}
Mas talvez eu esteja errado e haja uma solução simples. Alguma ideia?