scrollTargetLayout 不会将其目标视图居中

问题描述 投票:0回答:1

我正在研究一个轮播视图,将药丸捕捉到中心。我已经布置了以下课程,除了一些事情表现不佳之外,它在某种程度上有效。

struct AccountCarousel: View {
    
    struct AccountPill: View {
        @State var text: String
        
        var body: some View {
            VStack {
                Text(text)
            }.frame(width: 110, height: 80)
                .background(.red)
                .cornerRadius(30)
                .scrollTransition { view, transition in
                    view.opacity(transition.isIdentity ? 1 : 0.3)
                }
        }
    }
    
    var body: some View {
        ZStack {
            Spacer().frame(minWidth: 110, maxHeight: .infinity)
                .frame(width: 110)
                .background(.purple)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 15) {
                    ForEach(1..<10) { i in
                        AccountPill(text: "\(i)")
                    }
                }.scrollTargetLayout()
            }.scrollTargetBehavior(.viewAligned)
                .defaultScrollAnchor(.center)
                .safeAreaPadding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                .background(.gray)
        }
    }
}

发生了一些问题,我很想调整。

  1. 如您所见,滚动并未使项目居中。总是有点不对劲。
  2. 边缘药丸无法滚动到中心。
  3. 我希望淡出效果比当前晚一点触发(就在边缘)

我玩过插图、假物体等,但无法改变任何这些东西。

swiftui scroll
1个回答
0
投票

问题在

AccountPill
。您将滚动锚点设置为
.center
。然而,你也忽略了
HStack spacing
。重新计算
AccountPill
以适合,即 1/3 屏幕宽度,然后它应该可以工作。

Step:嵌套在HStack中,居中对齐。制作 2 个虚拟对象,前后

Spacer
对齐
pill view

struct AccountCarousel: View {
    
    var pillWidth: CGFloat {
        UIScreen.main.bounds.size.width / 3
    }
    
    struct AccountPill: View {
        
        let size: CGFloat
        
        @State var text: String
        
        var body: some View {
            HStack(alignment: .center) {
                Spacer()
                    .frame(width: 10)
                
                VStack {
                    Text(text)
                }
                //width have to minus both Spacer's width to align to center.
                .frame(width: size - 20, height: 80)
                .background(.red)
                .cornerRadius(30)
                .scrollTransition { view, transition in
                    view.opacity(transition.isIdentity ? 1 : 0.3)
                }
                
                Spacer()
                    .frame(width: 10)
            }
        }
    }
    
    var body: some View {
        ZStack {
            Spacer().frame(minWidth: pillWidth, maxHeight: .infinity)
                .frame(width: pillWidth)
                .background(.purple)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 0) { // <- Reduce to 0
                    ForEach(1..<10) { i in
                        AccountPill(size: pillWidth, text: "\(i)")
                    }
                }
                .scrollTargetLayout()
            }
            .scrollTargetBehavior(.viewAligned)
                .defaultScrollAnchor(.center)
                .background(.gray)
        }
    }
}

输出:

© www.soinside.com 2019 - 2024. All rights reserved.