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

Я пытался найти ответы на подобные вопросы, но у меня нет особого опыта, и у меня были проблемы с их выполнением, поэтому любая помощь будет очень признательна! Моя ситуация такова: когда я нажимаю кнопку в своем родительском ViewController, следующий код используется для вызова дочернего ViewController (кстати, дочерний элемент на самом деле является TableViewController, но, похоже, он работает нормально, «думая», что это нормальный Вьюконтроллер?):

controller = (storyboard?.instantiateViewController(withIdentifier: "People"))
addChildViewController(controller!)
controller?.view.frame = CGRect(x: 10, y: 200, width: 394, height: 300)
self.view.addSubview((controller?.view)!)
controller?.didMove(toParentViewController: self)

Что бы я хотел, так это передать массив из родительского в дочерний, где он будет использоваться в качестве данных TableView?

Во-вторых, когда я выбираю ячейку в дочернем TableView, я хотел бы, чтобы соответствующая информация была отправлена ​​​​родителю, а дочерний элемент исчез.
Если это представляет интерес, мне удалось закрыть дочерний элемент под различных обстоятельствах (когда щелчок происходит в родительском элементе при отображении дочернего элемента), используя следующее:

controller?.willMove(toParentViewController: nil)
controller?.view.removeFromSuperview()
controller?.removeFromParentViewController()

Я был бы очень признателен за любой совет, даже если это ссылка на что-то, что может помочь!


person jasperthedog    schedule 13.09.2017    source источник
comment
вы можете передавать массив точно так же, как вы передаете данные между любыми двумя контроллерами представления. после строки addChildViewController(controller!) можно просто добавить controller.array = self.array. и для возврата вы можете использовать метод делегата.   -  person Aju Antony    schedule 13.09.2017
comment
Вы можете создать свойство в экземпляре parentsViewVontroller и parentsViewVontroller's для childViewController и передать значение этой переменной ИЛИ вы можете сделать делегата childViewController и можете получать события обратно ИЛИ вы можете использовать блоки.   -  person TheTiger    schedule 13.09.2017


Ответы (3)


Вы можете передать значение из родительского в дочерний контроллер, как это

controller = (storyboard?.instantiateViewController(withIdentifier: "People"))
    addChildViewController(controller!)
    controller?.view.frame = CGRect(x: 10, y: 200, width: 394, height: 300)
    controller.tableDataSource = // Pass your required value to child controller
    self.view.addSubview((controller?.view)!)
    controller?.didMove(toParentViewController: self)

Теперь вы хотите вернуть выбранное вами значение в контроллер родительского представления. Для этого у вас есть делегат в ChildController, например

@protocol ChildControllerDelegate : class {
    func selectedValue(Value : String)
}

После этого сделайте переменную этого делегата в ChildController, как это

weak var delegate : ChildControllerDelegate?

и когда в методе rowDidSelect добавьте следующий код

if(delegate != nil) {
   delegate.selectedValue(Value :"Your selected value")
}

Теперь сделайте шаг, когда вы собираетесь показать ChildController из ParentController, в то время вам нужно установить этот объект delegate в ParentController, как это

controller = (storyboard?.instantiateViewController(withIdentifier: "People"))
    addChildViewController(controller!)
    controller?.view.frame = CGRect(x: 10, y: 200, width: 394, height: 300)
    controller.delegate = self
    self.view.addSubview((controller?.view)!)
    controller?.didMove(toParentViewController: self)

и после этого просто реализуйте метод делегата в ParentController вот так

func selectedValue(Value : String) {
   // you select val 
}
person Usman Javed    schedule 13.09.2017

Попробуйте это.

Сначала создайте общедоступный метод для добавления и удаления дочернего VC.

Для добавления дочернего виртуального канала.

public class func openChildViewController(parentVC:UIViewController, with childVC:UIViewController){

        parentVC.addChildViewController(childVC)
        childVC.view.frame = parentVC.view.frame
        parentVC.view.addSubview(childVC.view)
        parentVC.didMove(toParentViewController: childVC)
    }

Для удаления дочернего виртуального канала.

   public class func removeChildViewController(childVC:UIViewController){

        childVC.willMove(toParentViewController: nil)
        childVC.view.removeFromSuperview()
        childVC.removeFromParentViewController()
    }

Используйте описанный выше метод.

1.ParentVC.swift

class ParentVC: UIViewController , ChildVCDelegate  {

     var arrType = NSMutableArray()

    //add ChildVC
    @IBAction func btnAddChildVC(_ sender: UIButton) {
        let ChildVC = self.storyboard?.instantiateViewController(withIdentifier: "ChildVC") as! ChildVC
        PickerVC.arrPass = arrType //for data passing create any object in ChildVC for ex. arrPass is NSMutableArray
        ChildVC.delegate = self
        openChildViewController(parentVC: self, with: ChildVC)
    }

     // MARK: ChildVC Delegate
   func SetSelectedPickerValue(strSelectOption: String) {
                print(strSelectOption)
        }
    }

}

2.ChildVC.swift

class ChildVC: UIViewController{

    // MARK: Variable for ParentVCData Passing
     var arrPass = NSMutableArray()

    override func viewWillAppear(_ animated: Bool) {
        print(arrPass)
    }

    //Remove ChildVC
    @IBAction func btnRemoveChildVC(_ sender: UIButton) {
        self.delegate?.SetSelectedPickerValue!(strSelectOption: “any String you pass ChildVC To ParentVC”)
        removeChildViewController(childVC: self)
    }
}
// MARK: Create Delegate Method
@objc protocol ChildVCDelegate{
     @objc optional func SetSelectedPickerValue(strSelectOption:String)
}
person Dixit Akabari    schedule 13.09.2017

Вы можете:

  • Приведите controller к соответствующему классу для дочернего контроллера представления (я использую ChildViewController ниже, но, надеюсь, у вас есть более описательное имя); а также

  • Передайте массив (который, как я догадался, вы могли назвать people, но используйте любые имена ваших массивов в этих двух соответствующих контроллерах представления) от текущего контроллера представления (родительского) к этому новому дочернему контроллеру представления.

Таким образом:

let child = storyboard!.instantiateViewController(withIdentifier: "People") as! ChildViewController
addChildViewController(child)
child.people = people
child.view.frame = ...
view.addSubview(child.view)
child.didMove(toParentViewController: self)

Лично я бы не стал жестко кодировать дочерние координаты, как вы сделали в своем исходном вопросе. Я бы установил для translatesAutoresizingMaskIntoConstraints значение false, а затем добавил соответствующий ведущий/ замыкающие/верхние/нижние ограничения, но это на ваше усмотрение. Было слишком больно видеть жестко заданные координаты в вашем примере.

person Rob    schedule 13.09.2017
comment
Спасибо за совет! Я собирался сначала заставить все работать, а затем добавить автоматическое изменение размера (довольно новое для этого, поэтому я полагаю, что это может быть неправильный способ сделать что-то!) - person jasperthedog; 22.09.2017