Невозможно переключиться на другой дочерний контроллер представления в представлении контейнера - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть контроллер основного вида, контейнерное представление и 2 дочерних контроллера представления, и я хотел бы иметь возможность переключаться между дочерними (например: когда приложение загружается в первый раз, я хотел бы, чтобы контроллер содержалMapView для загрузки и когда я нажимаю панель поиска, найденную в главном окне, контроллер с таблицей для загрузки).Вот моя раскадровка: https://i.stack.imgur.com/rDPMe.png

MainScreen.swift

class MainScreen: UIViewController {

@IBOutlet private weak var searchBar: UISearchBar!
@IBOutlet private weak var ContainerView: UIView!
//private var openSearchBar: Bool?
private var openMapView: Bool = true
private var openPlacesList: Bool = false
private var containerView: ContainerViewController!

override func viewDidLoad() {
    super.viewDidLoad()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    //let containerView = segue.destination as? ContainerViewController
    if containerView == nil{
        containerView = segue.destination as? ContainerViewController
    }
    if openMapView == true{
        containerView!.moveToMapView()
    }
    else if openPlacesList == true{
        containerView!.MoveToOpenPlaces()
    }
  }
}
//search bar delegate functions
extension MainScreen: UISearchBarDelegate{
//detects when text is entered
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    openPlacesList = true
    openMapView = false
    containerView!.MoveToOpenPlaces()
  }
}

ContainerViewController.swift:

class ContainerViewController: UIViewController {

private var childViewController: UIViewController!

private var first: UIViewController?
private var sec: UIViewController?

override func viewDidLoad() {
    super.viewDidLoad()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "MainToMap"{

        first = segue.destination as! MapViewController
        self.addChild(first!)
        self.view.addSubview(first!.view)
        self.didMove(toParent: self)
    }else{
       sec = segue.destination as! PlacesListController
    }

    if(first != nil && sec != nil){
        interchange(first!,sec!)
    }
}

func interchange(_ oldVc: UIViewController,_ newVc: UIViewController ){
    oldVc.willMove(toParent: nil)
    self.addChild(newVc)
    self.view.addSubview(newVc.view)

    self.transition(from: oldVc, to: newVc, duration: 2, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
        newVc.view.alpha = 1
        oldVc.view.alpha = 0
    }, completion: { (complete) in
        oldVc.view.removeFromSuperview()
        oldVc.removeFromParent()
        newVc.willMove(toParent: self)
    })
}

func moveToMapView(){
    performSegue(withIdentifier: "MainToMap", sender: nil)
}

func MoveToOpenPlaces(){
    performSegue(withIdentifier: "MainToSearches", sender: nil)
}

}

Проблема в том, чтокогда я нажимаю на строку поиска, он вызывает метод interchange, а затем просто выдает ошибку SIGABRT 1.Я пробовал этот урок: https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html#//apple_ref/doc/uid/TP40007457-CH11-SW1 и многое другое, но пока не повезло.Я застрял здесь и не знаю, как решить эту проблему.

Стек: https://i.stack.imgur.com/Zqpm1.png SIGABR 1 Ошибка: https://i.stack.imgur.com/NBgEN.png

1 Ответ

0 голосов
/ 17 декабря 2018

Вы, кажется, пытаетесь вручную переключаться между дочерними контроллерами представления, но в то же время используете сегменты (которые выполняют свои собственные переходы для вас).Исключите переходы (кроме первоначального перехода, если вы используете раскадровку с «представлением контейнера») и просто вручную создайте экземпляры дочерних контроллеров представления, используя их идентификаторы раскадровки.Но не используйте segues, а затем попробуйте заменить контроллеры дочерних представлений в prepare(for:sender:).

Также, когда вы используете transition(from:to:duration:options:animations:completion:), вы не должны добавлять представления в представлениеиерархия себя.Этот метод делает это для вас (если вы не используете опцию showHideTransitionViews, которая сообщает методу, что вы берете это на себя, что нам не нужно здесь делать).Аналогично, когда вы используете опцию transitionCrossDissolve, вам также не нужно связываться с alphas.


Таким образом, используя фрагмент кода из той статьи, на которую вы ссылаетесь,Вы можете сделать:

class FirstViewController: UIViewController {

    @IBOutlet weak var containerView: UIView!  // the view for the storyboard's "container view"
    @IBOutlet weak var redButton: UIButton!    // a button to transition to the "red" child view controller
    @IBOutlet weak var blueButton: UIButton!   // a button to transition to the "blue" child view controller

    // tapped on "transition to red child view controller" button

    @IBAction func didTapRedButton(_ sender: UIButton) {
        redButton.isEnabled = false
        blueButton.isEnabled = true

        let oldVC = children.first!
        let newVC = storyboard!.instantiateViewController(withIdentifier: "RedStoryboardID")
        cycle(from: oldVC, to: newVC)
    }

    // tapped on "transition to blue child view controller" button

    @IBAction func didTapBlueButton(_ sender: UIButton) {
        blueButton.isEnabled = false
        redButton.isEnabled = true

        let oldVC = children.first!
        let newVC = storyboard!.instantiateViewController(withIdentifier: "BlueStoryboardID")
        cycle(from: oldVC, to: newVC)
    }

    func cycle(from oldVC: UIViewController, to newVC: UIViewController) {
        // Prepare the two view controllers for the change.
        oldVC.willMove(toParent: nil)
        addChild(newVC)

        // Get the final frame of the new view controller.
        newVC.view.frame = containerView.bounds

        // Queue up the transition animation.
        transition(from: oldVC, to: newVC, duration: 0.25, options: .transitionCrossDissolve, animations: {
            // this is intentionally blank; transitionCrossDissolve will do the work for us
        }, completion: { finished in
            oldVC.removeFromParent()
            newVC.didMove(toParent: self)
        })
    }

    func display(_ child: UIViewController) {
        addChild(child)
        child.view.frame = containerView.bounds
        containerView.addSubview(child.view)
        child.didMove(toParent: self)
    }

    func hide(_ child: UIViewController) {
        child.willMove(toParent: nil)
        child.view.removeFromSuperview()
        child.removeFromParent()
    }

}

Это дает:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...