Контроллер Push View из контроллера дочернего представления

У меня есть приложение, в котором есть «DadViewController», который содержит UIScrollView с включенным пейджингом. Каждая страница заполняется разными UIViewController.

Как мне нажать новый UIViewController нажатием кнопки в одном из контроллеров, содержащихся в UIScrollView?

class DadView: UIView {

    let model = DadModel()

    let scrollView: UIScrollView = {
        let view = UIScrollView()
        view.isPagingEnabled = true
        // Additional setup...
        return view
    }()



    override init(frame: CGRect) {
        super.init(frame: frame)
        setupScrollView()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }



    fileprivate func setupScrollView() {
        self.addSubview(scrollView)
        // Autolayout code to pin scrollview to all 4 sides

        let vc1 = VC1()
        scrollView.addSubview(vc1.view)
        vc1.view.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT)

        // Add additional view controller views with the appropriate frames...

    }
}

class DadController: UIViewController {
    var dadView: DadView!

    override func loadView() {
        super.loadView()
        dadView = DadView()
        view = dadView
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

class VC1: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .green
    }

}

person cabyambo    schedule 09.04.2019    source источник


Ответы (1)


Измените ваш DadView setupScrollView, чтобы он принимал экземпляр UIViewController в качестве аргумента. И не вызывайте этот метод в инициализации

class DadView: UIView {

    let model = DadModel()

    let scrollView: UIScrollView = {
        let view = UIScrollView()
        view.isPagingEnabled = true
        // Additional setup...
        return view
    }()



    override init(frame: CGRect) {
        super.init(frame: frame)
//        setupScrollView()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }



    fileprivate func setupScrollView(_ parentVC: UIViewController) {
        self.addSubview(scrollView)
        // Autolayout code to pin scrollview to all 4 sides

        let vc1 = VC1()
        vc1.view.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT)
        parentVC.addChild(vc1)
        scrollView.addSubview(vc1.view)
        vc1.didMove(toParent: parentVC)

        // Add additional view controller views with the appropriate frames...

    }
}

В DadViewController после создания экземпляра DadView вызовите метод setupScrollView с самим собой

class DadController: UIViewController {
    var dadView: DadView!

    override func loadView() {
        super.loadView()
        dadView = DadView()
        dadView.setupScrollView(self)
        view = dadView
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Затем вы можете получить родительский контроллер представления от дочернего контроллера представления и выполнить push

class VC1: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .green
    }
    @IBAction func buttonAction(_ sender: UIButton) {
        self.parent?.navigationController?.pushViewController(NewVC(), animated: true)
    }
}
person RajeshKumar R    schedule 09.04.2019
comment
Работает отлично! Мне просто нужно было изменить fileprivate на internal - person cabyambo; 09.04.2019
comment
@yambo я думаю, вы уже поняли это из комментариев, приведенная выше демонстрация - это вопрос передачи кода - person Sh_Khan; 09.04.2019
comment
@Sh_Khan Я не знаю, почему тебе все не нравится, но этот ответ очень краток и отвечает на вопрос. - person cabyambo; 09.04.2019
comment
Потому что программист должен получить это даже из слова, не нужно перечислять код. Разве вы не поняли это из комментариев? - person Sh_Khan; 09.04.2019
comment
@RajeshKumar_R Этот вопрос немного не по теме. Но теперь, когда я могу переходить к другим контроллерам представления из этих дочерних контроллеров, знаете ли вы, как я реализую свои пользовательские переходы контроллера представления? Ни одна из функций делегата NavigationController не вызывается на дочерних контроллерах, когда я перехожу к новому контроллеру. - person cabyambo; 10.04.2019
comment
@yambo в вашем дочернем контроллере просмотра добавьте self.parent.navigationcontroller.delegate = self. - person RajeshKumar R; 10.04.2019
comment
@RajeshKumarR Я так и думал. Но когда я делаю print(self.parent.navigationcontroller) в дочерних контроллерах viewDidLoad, он печатает ноль. Вы знаете причину этого? - person cabyambo; 10.04.2019
comment
@yambo Вы встроили свой DadViewController в навигационный контроллер? - person RajeshKumar R; 10.04.2019
comment
@RajeshKumarR Да. В делегате приложения у меня есть следующее window?.rootViewController = UINavigationController(rootViewController: DadController()) - person cabyambo; 10.04.2019
comment
Обновление: в этом посте все прояснилось stackoverflow.com/questions/10982567/ - person cabyambo; 10.04.2019