Как бы я передавал данные из контроллера представления в представление контейнера? - PullRequest
1 голос
/ 06 мая 2019

enter image description here

Я пытаюсь передать данные из ViewController в контейнер внутри него.Когда я нажимаю кнопку, делегат отправляет данные в контейнер, но размер контейнера изменяется.Как бы мне этого не допустить?Я думаю о prepareForSegue функции, но я не могу понять, как ее реализовать, но я не знаю, будет ли даже это решением.

protocol VCDelegate {

    func passData(theData1:String)

}

class ViewController: UIViewController {

    var delegate : VCDelegate?

    @IBAction func sendTextToContainer(_ sender: Any) {

        let ViewC = self.storyboard!.instantiateViewController(withIdentifier: "ViewController") as! ViewController

        let ContainerV = self.storyboard!.instantiateViewController(withIdentifier: "ContainerView") as! ContainerView

        self.present(ContainerV,animated:true,completion: nil)

        ViewC.delegate = ContainerV

        ViewC.delegate?.passData(theData1:"Hello")
    } 
}

class ContainerView: UIViewController, VCDelegate {

    func passData(theData1: String) {

        print(theData1)
        theText.text = theData1

    }

    @IBOutlet weak var theText: UILabel!

    override func viewWillAppear(_ animated: Bool) {

    }

}

1 Ответ

2 голосов
/ 06 мая 2019

Вы создаете новый, второй экземпляр дочернего контроллера представления. Но если вы создали «контейнер» в IB, он уже создан для вас.

Существует два способа передачи данных дочернему контроллеру родительского контроллера. Вы можете передать исходные данные в prepare(for:sender:):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? SecondViewControllerProtocol {
        destination.passData(string: "Initial value")
    }
}

Если вы хотите позже обновить его, вы можете получить соответствующую children:

@IBAction func didTapButton(_ sender: Any) {
    for child in children {
        if let child = child as? SecondViewControllerProtocol {
            child.passData(string: "Updated value")
        }
    }
}

(Вы, очевидно, можете сохранить ссылку, которую вы захватили во время prepare(for:sender:), если хотите).

Затем контроллер второго представления может обновить свою метку соответствующим образом:

protocol SecondViewControllerProtocol {
    func passData(string: String) 
}

class SecondViewController: UIViewController {
    @IBOutlet weak var label: UILabel!

    private var string: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        // this is in case you passed the data before the label was hooked up

        label.text = string
    }
}

extension SecondViewController: SecondViewControllerProtocol {
    func passData(string: String) {
        self.string = string

        guard let label = label else { return }

        UIView.transition(with: label, duration: 0.25, options: .transitionCrossDissolve, animations: {
            label.text = string
        }, completion: nil)
    }
}

Что дает:

enter image description here

...