SwiftUI:当ScrollView中的View更改大小时保持滚动位置

1u4esq0p  于 2024-01-05  发布在  Swift
关注(0)|答案(1)|浏览(168)

目标

我有一个项目列表,每个项目都可以展开以显示一些额外的内容。但是,当展开/折叠项目时,滚动位置有时会跳来跳去。当一个项目改变大小时,有没有办法保持滚动位置?

理想情况下,展开/折叠视图的上边缘应保持在屏幕上的固定位置。

替代设计?

或者,这种扩展风格在iOS上是否不合适?如果是,是否有推荐的最佳实践来显示更多内容(如查看“更多评论”,扩展引用,查看更长的标题等)。

尝试解决方案

  • 使用ScrollViewReader和scrollTo()-不幸的是,扩展的Bool toggle和scrollTo的时间不一致。这意味着视图有时会在大小调整之前滚动(因此会落在错误的位置)。我尝试了几种排列,将两个动作分组在同一个withAnimation块,Tasks等中-但它总是看起来很不正确
  • .scrollPosition()修改器-仅在iOS 17中可用,因此实际上在相当长的一段时间内不会适用于大多数用户
  • withAnimation完成块-也仅在iOS 17中

示例代码

struct MyList: View {
    var items: [String] = ["Item A", "Item B", "Item C", "Item D", "Item E", "Item F", "Item G", "Item H", "Item I", "Item J" ]
    
    var body: some View {
        ScrollView {
            LazyVStack(alignment: .center) {
                ForEach(items, id: \.self) { item in
                    ItemView(item: item)
                }
            }
            .background(.ultraThinMaterial)
        }
    }
}

struct ItemView: View {
    var item: String
    
    @State var expanded: Bool = false
    
    var body: some View {
        
        VStack {
            Text(item)
            Spacer(minLength: 50)
            Button("Expand/Collapse") {
                expanded.toggle()
            }
            if expanded {
                Text("Shown When Expanded")
                Text("\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -\n -")
            }
        }
        .frame(maxWidth: .infinity)
        .background()
        .padding(.bottom)
    }
}

字符串
x1c 0d1x的数据

vlurs2pr

vlurs2pr1#

使用VStack而不是LazyVStack,你会得到你想要的行为:

struct MyList: View {
    var items: [String] = ["Item A", "Item B", "Item C", "Item D", "Item E", "Item F", "Item G", "Item H", "Item I", "Item J" ]
    
    var body: some View {
        ScrollView {
            VStack(alignment: .center) {
                ForEach(items, id: \.self) { item in
                    ItemView(item: item)
                }
            }
            .background(.ultraThinMaterial)
        }
    }
}

字符串

相关问题