SwiftUI 从页面向 PageViewController 发送动作

SwiftUI send action from a page to the PageViewController

我已经在 SwiftUI 中设置了一个 PageViewController,遵循已知的教程 Interfacing with UIKitUIViewControllerRepresentable

我的控制器阵列由简单的 SwiftUI 视图组成。我传递了一个简单的 IntroPage 结构来提供内容。视图是嵌套的,这是 SwiftUI 的良好做法,因此:

PageView
-   IntroScreen                // part of the pages array
    -   VStack 
        -   Text
        -   Image
        -   ButtonView         // a separate view struct
            - HStack
                - ForEach      // iterating through the buttons in my IntroPage Object
                    - Button
PageControl

现在我想在这些视图上添加一些 按钮 。它们应该可以通过我的 IntroPage 结构进行配置。其中一个前进到 PageViewController 中的下一页,另一个告诉 PageViewController 首先添加更多页面,另一个按钮关闭整个 PageViewController。

我想不通,如何访问 PageViewController 中的这些方法,在哪里实现它们(实例视图?PageViewController 的协调器?)以及如何到达我需要的对象(例如 currentPage PageViewController的绑定变量).

比如我在PageViewController的coordinator中实现了一个forward()函数:

func forward() {
   if parent.currentPage < parent.controllers.count - 1 {
       parent.currentPage += 1
   }
}

...如果我在最终视图的 PageView 旁边添加一个按钮,效果很好,有动画等等。但是我仍然无法从子视图中包含的按钮调用它。

有什么想法吗?

编辑:根据要求,这是 ButtonView 中的一种情况。

struct IntroButtonView: View {
    var page: IntroPage
    var body: some View {
        HStack() {
           Button(action:dismiss) {
              Text("LocalizedButtonTitle")
           }
           // ... more buttons, based on certain conditions
        }
    }

    func dismiss() { 
         // how to dismiss the modally presented controller ?
    }

    func next()    { 
         // how to advance to the next page
    }

    func expand()  { 
         // how to add more pages to the pages array
    }
}

或许我完全错了,我仍然认为 "events" 而不是 "declaration"...

好的,我明白了。一开始并不直观,我不得不说。来自传统的基于事件的编程,这是一种完全不同的思维方式

我在视图的主实例中使用了一个 @State 变量。

我使用 @Binding 变量来处理上游(ViewControllers、Controls)和下游(子视图)的状态。因此,例如,我使用一个变量来告诉 UIPageViewControllerdataSource 是否 return 视图控制器 before/after 当前视图控制器。

为了关闭模态呈现的控制器,我使用了

@Environment(\.presentationMode) var presentationMode

...

func dismiss() {
  self.presentationMode.wrapptedValue.dismiss()
}

同样,

...
@Binding var currentPage: int
...

Button(action: next) { Text("Next Page") }
...

...
func next() {
    currentPage += 1
}

在决定如何嵌套视图以及为绑定选择哪些变量时有一些注意事项,但现在我很清楚了。最大的问题最终是“真相来源”应该锚定在哪里。事实证明,就在“中间”,即在控制器下方和特定视图上方。

希望这对寻找类似内容的其他人有用。