3

我已经在 SwiftUI 中设置了一个PageViewController,遵循已知的 Tutorial Interface 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 的协调器?)以及如何访问我需要的对象(例如currentPagePageViewController 的 Binding 变量)。

例如,我forward()在 PageViewController 的协调器中实现了一个函数:

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
    }
}

或者也许我完全错了,仍然从“事件”而不是“声明”的角度思考......

4

1 回答 1

2

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

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

我使用@Binding变量来处理上游(ViewControllers、Controls)和下游(子视图)的状态。因此,例如,我使用一个变量来告诉if 或不返回当前视图控制器之前/之后的视图控制器dataSourceUIPageViewController

为了解除我使用的模态呈现的控制器

@Environment(\.presentationMode) var presentationMode

...

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

相似地,

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

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

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

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

希望这对寻找类似东西的其他人有用。

于 2020-05-28T22:29:12.173 回答