如何从容器视图更新父视图/视图控制器的元素?

4
我有一个ViewController,其中包含一个ContainerView。 因此,我为ViewController()添加了一个类,为ContainerViews ViewController()添加了一个类。为了更好地说明它,我附上了一个storboard场景的照片:enter image description here 当我点击ContainerView中的按钮时,我想使用不同的文本更新标签,我该如何实现? 重要提示:ContainerViews按钮是一个在单独的ViewController中的IBAction,我想在单独的ViewController()类中更新IBOutlet。非常感谢您的帮助!

据我所知,你可以通过容器中的视图控制器的父级视图控制器属性访问"parent"。如果不行,可以查看NSNotificationCenter或者创建一个委托。 - Fred Faust
是的,通过parentViewController!.view.backgroundColor可以访问父视图的背景颜色。例如,这样可以正常工作。但是,我如何访问父视图的outlets呢? - Tom el Safadi
你可能需要将其强制转换为它的视图控制器子类。(self.parentViewController as! 你的UIViewController子类).someProperty - Fred Faust
1
非常感谢,这对我有用!!! :))) - Tom el Safadi
1个回答

2

获取容器视图中的父视图控制器并将其强制转换为您的父控制器类型(如thefredelement的评论中所提到的)将起作用,但它有一些缺点。

  1. 你的容器视图应该只是一个MVC本身。 作为视图,它不应该知道谁在控制它,但它可能会知道它有一个代理可以发送消息给它。例如,UITextView知道它是哪个类的视图控制器的子级吗? 不,但它知道它可能有一个代理可以发送消息给它。
  2. 由于与父类紧密耦合,您无法将此视图控制器重新用作任何其他视图控制器的子级
  3. 通过仅将接收的父级强制转换为父级类型,您正在绕过类型检查。

因此,“快速修复”可能是按照评论中建议的进行操作,但我提供这个答案是作为我认为长期处理应该如何处理的建议。 希望其他人找到它有用。 我知道对我来说经过思考过程很有帮助。

理想情况下,我认为您应该在ContainerViewController中声明一个变量,该变量要么是您父视图控制器的类,要么更好的是一个您父控制器将符合的协议。 然后,在父视图控制器的prepareForSegue中设置此变量。

与此同时,您的父级应该(或者至少可以)声明一个变量,其类型为容器视图的类型或容器将符合的另一个协议。然后,在父级的准备转场时,获得Container视图控制器的句柄并将其存储在您声明的变量中。

像这样:

在您的ContainerViewController中

var myContainerViewDelegate: ParentViewControllerOrProtocol

在您的父视图控制器中:
weak var myChildViewOutlet:  ChildViewControllerOrProtocol

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  if segue.identifier == "embededSegueToChild" {
    if let dvc = segue.destinationViewController.contentViewController as?  ChildViewControllerOrProtocol {
      dvc.myContainerViewDelegate = self
      myChildViewOutlet = dvc
    }
  }

这样,您的ContainerViewController看起来像是视图对象(我认为这就是它应该被考虑的),而myChildViewOutlet变量是您对该视图的outlet(可能应该是弱引用)。
在容器中,myContainerViewDelegate引用本质上将您的父级设置为容器视图控制器的代理。
现在,两个视图控制器都拥有彼此的句柄。

非常感谢您详细的回答。但是我不太明白我在哪里可以访问标签?该标签放置在视图控制器中,就像上面的图片一样。如果我没有理解,对不起:D - Tom el Safadi
你搞清楚了吗?基本上,你可以通过 Container 视图中的 myContainerViewDelegate 变量访问标签。它可能就像 myContainerViewDelegate.labelVariable.text 这么简单。从这个角度来看,它与之前获取父视图控制器并没有太大的区别。不同之处在于,父视图设置自己为委托,并且子视图除了应该实现的协议之外,对父视图没有任何了解(如果你选择协议路线)。 - nPn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接