【问题标题】:SwiftUI: Call a function of a programmatically created viewSwiftUI:调用以编程方式创建的视图的函数
【发布时间】:2022-07-21 01:12:38
【问题描述】:

当在以编程方式调用抽象视图的视图中按下按钮时,我试图让 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 内的一个结构中的数组中,每个AbstractedView 都有一个ScrollViewReader,那会起作用吗?我觉得好像必须有更好的方法来实现这一点,我只是不知道该怎么做。我是 Swift 新手,非常感谢您的帮助。

附:我听说过 UIKit,但我对此一无所知,现在是使用它的合适时机吗?

【问题讨论】:

  • 尝试在不同的 View 上“调用函数”与 SwiftUI 的原则有些对立。如果您需要 AbstractedView 对某些状态变化做出反应,请将状态存储在父视图 (HigherView) 中并通过 props 向下传递。
  • 我首先尝试这样做,但我找不到让ScrollView 在状态更改时调用scrollToView2() 的方法。
  • 我知道.OnChange(of:) 修饰符,但我不知道在这种情况下如何使用它
  • 这样不行,scrollTo 需要一个 ID 滚动到(每个事件)。请参阅此处,例如 stackoverflow.com/a/60855853/12299030
  • 谢谢@Asperi

标签: swift xcode swiftui


【解决方案1】:

使用来自 @Asperi 和 @jnpdx 的 cmets,我能够提出比我需要的更强大的解决方案:

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 {
    @StateObject 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
                            }
                        }
                    }
                }
            }
        }
    }
}

谢谢你们!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多