此代码显示了一个封面流样式视图,您可以在其中滚动浏览滚动视图中的图像,而图像本身来自数组。间距为 -100,以使不在屏幕中间的其他图片出现在当前图片后面。虽然这在左侧运行良好,但在当前图像的右侧,ScrollView 中的其他图像相交:(
纸飞机在中间,下载符号在它前面)
使用 zIndex,我希望在用户滚动浏览图库时动态更新视图。我尝试使用 GeometryReader 和 @State var selectedItemInd,但效果不佳,因为视图没有更新。我相信每次用户滚动时,我不仅需要知道哪个项目处于中间位置,还需要知道所有其他项目的位置。
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()
}
但也许我错了,有一个简单的解决方案。有什么想法吗?