Swift: как программно продвигать UIPageViewController, который находится внутри представления контейнера?

У меня есть один ViewController, который содержит кнопку и два представления изображений, которые я хотел бы оставить навсегда, и PageViewController, который прокручивает три других ViewController, и все это работает хорошо, однако я не могу понять, как это сделать. перейти к следующему слайду программно при нажатии кнопки.

Вот как выглядит мой класс PageController (на основе очень полезного ответа Fattie здесь: UIPageViewController и раскадровка):

class PageController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {


var pages = [UIViewController]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.delegate = self
    self.dataSource = self

    let p1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "onboardingText01")
    let p2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "onboardingText02")
    let p3: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "onboardingText03")

    pages.append(p1)
    pages.append(p2)
    pages.append(p3)

    setViewControllers([p1], direction: UIPageViewController.NavigationDirection.forward, animated: false, completion: nil)

}


func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController)-> UIViewController? {

    let currentPage = pages.index(of: viewController)!

    // used to prevent the PageViewController from looping
    if currentPage == 0 { return nil }

    let prev = abs((currentPage - 1) % pages.count)
    return pages[prev]

}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController)-> UIViewController? {

    let currentPage = pages.index(of: viewController)!

    // used to prevent the PageViewController from looping
    if currentPage == (pages.count - 1) { return nil }

    let nxt = abs((currentPage + 1) % pages.count)
    return pages[nxt]
}

func presentationIndex(for pageViewController: UIPageViewController)-> Int {
    return pages.count
}

}

Затем кнопка определяется как действие в ViewController, содержащее все это (отдельный файл).

Я пытался использовать уведомление/наблюдатель, но получаю сообщение об ошибке

Тип «UIPageViewController» не имеет члена «advancePage»

с селектором (я не уверен, как вызвать функцию).

Внутренний видDidLoad:

NotificationCenter.default.addObserver(self, selector: #selector(UIPageViewController.advancePage()), name: advance, object: nil)

Внутри класса UIPageViewController

    func advancePage(){
        setViewControllers(pages,
                           direction: UIPageViewController.NavigationDirection.forward,
                           animated: true,
                           completion: nil)
    }

Любые идеи?


person CristianMoisei    schedule 16.03.2019    source источник
comment
Кристиан, прежде чем я полностью рассмотрю ваш вопрос. Возможно это может помочь Это полное руководство по представлениям контейнеров от красивого члена списка! stackoverflow.com/a/23403979/294884 Обратите особое внимание на критический раздел Как подключиться к дочернему контроллеру. .. (около середины)   -  person Fattie    schedule 16.03.2019


Ответы (1)


Вам нужно добавить это внутрь PageController viewDidLoad

NotificationCenter.default.addObserver(self, selector: #selector(self.advancePage), name: advance, object: nil)

@objc func advancePage(_ note:NSNotification){
person Sh_Khan    schedule 16.03.2019
comment
Спасибо, но я попробовал это, и я получаю: значение типа «PageController» не имеет члена «advancePage» - person CristianMoisei; 16.03.2019
comment
Редактировать: я идиот, я слишком много раз нажимал кнопку отмены и возвращался к UIPageViewController. вместо себя. - person CristianMoisei; 16.03.2019
comment
это #selector(self.advancePage) не #selector(UIPageViewController.advancePage()) - person Sh_Khan; 16.03.2019
comment
Это сработало, спасибо. Нажатие кнопки приводит к сбою приложения с этой ошибкой: Завершение приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Количество предоставленных контроллеров представления (3) не соответствует количеству, необходимому (1) для запрошенного перехода», поэтому я предположим, что-то не так с моей функцией? - person CristianMoisei; 16.03.2019
comment
Я нашел и решил проблему с вашей помощью, еще раз спасибо. Я обновлю вопрос, чтобы он был у других, и выберу ваш ответ в качестве ответа. - person CristianMoisei; 16.03.2019
comment
вместо pages поставьте pages[nextIndex], где nextIndex — индекс, который нужно показать - person Sh_Khan; 16.03.2019
comment
Не редактируйте ответ в вопросе - обновите этот ответ, чтобы отразить то, что вы установили в комментариях и т. Д., Или напишите новый ответ. - person Caleb; 16.03.2019
comment
Все в порядке, исправление - это то, что вы предложили, поэтому вся информация здесь. - person CristianMoisei; 16.03.2019
comment
@Sh_Khan, извините, что снова беспокою вас, но не знаете ли вы, как заставить элемент управления страницей (точки) работать с этой настройкой? Все ответы, которые я нахожу, говорят, что он должен работать автоматически, пока я предоставляю функции PresentationIndex и PresentationCount (что я и делаю), но я не думаю, что они работают, если я хочу, чтобы точки были на родительском ViewController. - person CristianMoisei; 16.03.2019
comment
см. здесь samwize.com/2016/03/08/, но обязательно используйте обновленную сигнатуру метода swift 3 - person Sh_Khan; 16.03.2019