繁体   English   中英

单击列表项时滚动到 SwiftUI 中的正确位置

[英]Scroll to correct position in SwiftUI when a list item is clicked

我有一个 SwiftUI ForEach循环,其中包含单击时展开的视图。 类似于下面显示的视图。

struct ExpandingView: View {
    
    @State var isExpanded = false
    
    var body: some View {
        VStack {
            Text("Hello!")
            if isExpanded {
                Text("World")
            }
        }
        .onTapGesture {
            withAnimation {
                isExpanded.toggle()
            }
        }
    }
}

理论上,我可以使用ScrollViewReaderscrollTo特定位置。

ScrollViewReader { view in
    ScrollView {
        ForEach(0...100, id: \.self) { id in
             ExpandingView()
                 .id(id)
                 .padding()                        
        }
    }
}

但是,实际上,我不确定如何从视图中获取id (因为onTapGesture在视图中)并将其向上传播一层。

另一种选择是在ForEach循环中使用onTapGesture ,但是我不确定如何切换isExpanded标志以获得正确的视图。

您可以将ScrollViewProxy传递给行视图,然后您现在可以滚动。

struct ExpandingView: View {
    
    @State var isExpanded = false
    var id: Int
    var proxy: ScrollViewProxy
    var body: some View {
        VStack {
            Text("Hello!")
            if isExpanded {
                Text("World")
            }
        }
        .onTapGesture {
            withAnimation {
                isExpanded.toggle()
                proxy.scrollTo(id, anchor: .center)
            }
        }
    }
}

struct TestScrollView: View {
    var body: some View {
        ScrollViewReader { view in
            ScrollView {
                ForEach(0...100, id: \.self) { id in
                    ExpandingView(id: id, proxy: view)
                        .id(id)
                        .padding()
                }
            }
        }
    }
}

在此处输入图片说明

如果我正确理解您的问题,您会问如何将“ContentView ScrollView”中的 id 传递到 ExpandingView。 试试这个:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}           
struct ExpandingView: View {
    @State var worldId: Int
    @State var isExpanded = false
    
    var body: some View {
        VStack {
            Text("Hello!")
            if isExpanded { Text("World \(worldId)") }
        }.onTapGesture {
            withAnimation { isExpanded.toggle() }
        }
    }
}

struct ContentView: View {
    var body: some View {
        ScrollViewReader { view in
            ScrollView {
                ForEach(0...100, id: \.self) { id in
                    ExpandingView(worldId: id).id(id).padding()
                }
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM