我试图让SwiftUI ScrollView滚动到抽象视图中的某个点,当在以编程方式调用抽象视图的视图中按下按钮时.这是我的代码:

struct AbstractedView: View {
    @Namespace var view2ID

    var body: some View {
        ScrollView {
            VStack {
                View1()
                View2()
                .id(view2ID)
                View3()
            }
        }
    }
    func scrollToView2(_ proxy: ScrollViewProxy) {
        proxy.scrollTo(view2ID, anchor: .topTrailing)
    }
}

如您所见,当调用scrollToView2()(在ScrollViewReader中)时,AbstractedView滚动到view2ID.我在不同的视图中以编程方式创建了许多AbstractedView:

struct HigherView: View {
    var numAbstractedViewsToMake: Int

    var body: some View {
        VStack {
            HStack {
                ForEach (0..<numAbstractedViewsToMake, id: \.self) { _ in
                    AbstractedView()
                }
            }
            Text("button")
            .onTapGesture {
                /* call each AbstractedView.scrollToView2()
            }
        }
    }
}

如果我将这些视图存储在我的HigherView中的一个 struct 中的一个数组中,每个AbstractedView有一个ScrollViewReader,这行得通吗?我觉得应该有更好的方法来实现这一点,我只是不知道该怎么做.我是Swift的新手,谢谢你的帮助.

P、 我听说过UIKit,但我对它一无所知,现在是使用它的时候吗?

推荐答案

使用@Asperi和@jnpdx的 comments ,我能够想出一个比我需要的更强大的解决方案:

class ScrollToModel: ObservableObject {
    enum Action {
        case end
        case top
    }
    @Published var direction: Action? = nil
}

struct HigherView: View {
    @StateObject var vm = ScrollToModel()
    var numAbstractedViewsToMake: Int

    var body: some View {
        VStack {
            HStack {
                Button(action: { vm.direction = .top }) { // < here
                    Image(systemName: "arrow.up.to.line")
                      .padding(.horizontal)
                }
                Button(action: { vm.direction = .end }) { // << here
                    Image(systemName: "arrow.down.to.line")
                      .padding(.horizontal)
                }
            }
            Divider()
            HStack {
                ForEach(0..<numAbstractedViewsToMake, id: \.self) { _ in
                    ScrollToModelView(vm: vm)
                }
            }
        }
    }
}

struct AbstractedView: View {
    @ObservedObject var vm: ScrollToModel

    let items = (0..<200).map { $0 } // this is his demo
    var body: some View {
        VStack {
            
            ScrollViewReader { sp in
                ScrollView {
               
                    LazyVStack { // this bit can be changed accordingly
                        ForEach(items, id: \.self) { item in
                            VStack(alignment: .leading) {
                                Text("Item \(item)").id(item)
                                Divider()
                            }.frame(maxWidth: .infinity).padding(.horizontal)
                        }
                    }.onReceive(vm.$direction) { action in
                        guard !items.isEmpty else { return }
                        withAnimation {
                            switch action {
                                case .top:
                                    sp.scrollTo(items.first!, anchor: .top)
                                case .end:
                                    sp.scrollTo(items.last!, anchor: .bottom)
                                default:
                                    return
                            }
                        }
                    }
                }
            }
        }
    }
}

谢谢你们!

Swift相关问答推荐

使用SWIFT宏从另一个枚举添加 case

如何消除SwiftUI中SF符号的填充

依赖于@Environment的init@StateObject

SWIFT Vapor控制台应用程序-操作无法完成.权限被拒绝

如何避免切换视图递归onChange调用SwiftUI

与视图交互使工具栏&;标题消失

为什么变量不存储在 Swift 的过程数据区中

VisionOS TabBar预览中是否存在漏洞?

当字符串包含 \r\n 时,NSRegularExpression 不起作用

如何打印出此 struct 中的数据?

Pod lib lint 命令找不到 watchos 模拟器

如何从另一个 swift 文件中调用函数

将基于MyProtocol的泛型函数的参数更改为使用存在的any MyProtocol或some MyProtocol是否会受到惩罚?

Swift-如何接受多个(联合)类型作为参数

NSFontAttributeName 已更改为 String

Xcode 6 中的嵌入式内容包含 Swift 代码构建设置有什么作用?

将强制向下转换视为可选将永远不会产生零

为 UIImagePicker 设置委托返回错误

如何在 SwiftUI 中创建带有图像的按钮?

Swift 的 JSONDecoder 在 JSON 字符串中有多种日期格式?