Передача данных в представление дочернего контейнера

Я хочу передать строковые данные из родительского vc в дочерний vc в swift 3.
Мой дочерний vc — это представление контейнера. Так что смотрите мой код:

class ParentViewController: UIViewController
@IBOutlet var continerView: UIView!
override func viewDidLoad() {
        super.viewDidLoad()
let vc = storyboard?.instantiateViewController(withIdentifier: "ChildVCID") as! ChildViewController!
        vc?.myStr = "Hello Bro"
        addChildViewController(vc!)
        continerView.addSubview((vc?.view)!)
        didMove(toParentViewController: vc)
}
}  

И мой дочерний код:

class ChildViewController: UIViewController
 var myStr:String!
override func viewDidLoad() {
        super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
        print("Str is: ",myStr)
    }

Итак, эта ошибка будет отображаться:
введите здесь описание изображения

Поэтому как это исправить?


person reza_khalafi    schedule 31.01.2017    source источник
comment
можешь прикрепить свой проект   -  person Anbu.Karthik    schedule 31.01.2017
comment
пожалуйста, идите шаг за шагом, например, просто не передавайте данные напрямую, попробуйте сначала загрузить представление (добавить подвид). Если это успешно, то передайте данные, попробуйте изменить код var myStr:String! в var myStr:String?. Я уверен, что ваш код правильный, только вы что-то упустили с опциями.   -  person ViJay Avhad    schedule 31.01.2017
comment
Пожалуйста, отформатируйте код правильно. Хотя бы проверьте правильность настройки. Есть много проблем, которые я могу определить. Ни в одном из классов нет открывающей скобки, вызова super.viewDidAppear нет, выравнивание кода, пробелы между функциями, принудительное разворачивание — это зло... и т.д.   -  person Oleg Danu    schedule 31.01.2017
comment
@OlegDanu правильно братан. Это просто необязательная привязка, где он напортачил. Я попробовал фрагмент кода из ChildViewController, измените var myStr:String! в var myStr:String? , ваше приложение не будет аварийно завершено.   -  person ViJay Avhad    schedule 31.01.2017
comment
Я предлагаю добавить super.viewDidAppear(animated) в качестве первой строки ChildViewController viewDidAppear. Я не думаю, что это является причиной аварии.   -  person Mobile Dan    schedule 31.01.2017
comment
Я попробовал тот же код, чтобы воспроизвести проблему, но он работал нормально.   -  person Amit Tandel    schedule 31.01.2017
comment
Попробуйте добавить super.viewDidAppear(анимированный) в viewDidAppear дочерних VCs, предложенный @MobileDan   -  person Amit Tandel    schedule 31.01.2017
comment
Я думаю, что didMove(toParentViewController: vc) должно быть didMove(toParentViewController: self)   -  person Mobile Dan    schedule 31.01.2017


Ответы (2)


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

class ParentViewController: UIViewController {
    @IBOutlet var continerView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let childViewController = storyboard?.instantiateViewController(withIdentifier: "ChildVCID") as? ChildViewController else {
            print("Creating ViewController from ChildVCID failed")
            return
        }

        childViewController.myStr = "Hello Bro!"
        addChildViewController(childViewController)
        continerView.addSubview(childViewController.view)
        didMove(toParentViewController: self)

    }
}

class ChildViewController: UIViewController {
    var myStr:String?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("Str is: ", myStr ?? "(nil)")
    }
}
person Mobile Dan    schedule 31.01.2017

Что бы ни было написано в вопросе, это правильно, всем просто не хватает одной важной вещи, когда в центре внимания раскадровки, поскольку ChildViewController в раскадровке уже встроен в ContainerView с помощью embed seague, который автоматически загружает этот vc в контейнер, и приложение разбилось из-за того, что 'myStr' был принудительно развёрнут, в то время как равен нулю,

Я написал ParentViewController, минимальный '!' & '?', зачем их использовать, если они не нужны.

 class ParentViewController: UIViewController{
    @IBOutlet var cv: UIView!
    override func viewDidLoad() {
     super.viewDidLoad()
     let storyBoard = UIStoryboard(name: "Main", bundle: nil)
     let vc = storyBoard.instantiateViewController(withIdentifier: "idChildViewController") as! ChildViewController
     vc.myStr = "Hello Bro"
     addChildViewController(vc)
     cv.addSubview(vc.view)
     didMove(toParentViewController: vc)
    }
   }
 }

Теперь, в ChildViewController, зачем объявлять переменную необязательным,

  class ChildViewController: UIViewController
   var myStr:String?  // or var myStr = "" //best way to declare string 
   override func viewDidLoad() {
       super.viewDidLoad()
   }
   override func viewDidAppear(_ animated: Bool) {
      print("Str is: ",myStr)
   }

Запустите приложение, оно выдаст консольный вывод в два раза больше, чем ,

Str is: nil // загружается из раскадровки

Str is: Optional("Hello Bro") // загружается из родителя

person ViJay Avhad    schedule 31.01.2017