SwiftUI отправляет действие со страницы в PageViewController

Я создал PageViewControllerв SwiftUI, следуя известному руководству по взаимодействию с UIKit, сUIViewControllerRepresentable и т.п.

Мой набор контроллеров состоит из простых представлений SwiftUI. Я прохожу простойIntroPagestruct для предоставления содержимого. Представления вложены, как это принято в 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).

Например, я реализовал 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
    }
}

Или, может быть, я совершенно не прав и до сих пор думаю скорее "событиями", чем "декларациями"...

1 ответ

Решение

Хорошо, я разобрался. Должен сказать, сначала не интуитивно. Исходя из традиционного программирования, основанного на событиях, это совсем другой образ мышления.

Я использовал @State переменная в основном экземпляре представления.

я использовал @Bindingпеременные для работы с состоянием как в восходящем (ViewControllers, Controls), так и в нисходящем (subviews). Так, например, я использовал переменную, чтобы сообщитьdataSource из UIPageViewController если или нет возвращать контроллер представления до / после текущего.

Для удаления модально представленного контроллера я использовал

@Environmen(\.presentationMode) var presentationMode

...

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

При принятии решения о том, как вложить представления и какие переменные выбрать для привязок, было несколько предостережений, но теперь для меня это ясно. В конечном итоге самая большая проблема заключалась в том, где должен быть закреплен "источник истины". Оказалось, прямо "посередине", то есть под контроллером и над отдельными видами.

Надеюсь, это будет полезно для других, которые ищут что-то подобное.

Другие вопросы по тегам