Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xcode 将事件分派到swift中的父ViewController_Xcode_Actionscript 3_Swift_Uiview_Uicontainerview - Fatal编程技术网

Xcode 将事件分派到swift中的父ViewController

Xcode 将事件分派到swift中的父ViewController,xcode,actionscript-3,swift,uiview,uicontainerview,Xcode,Actionscript 3,Swift,Uiview,Uicontainerview,我来自as AS3的背景,所以我可以更容易地向您展示我试图用AS3做什么。我有一个UIViewController(根),里面有一个ContainerView。我的印象是容器视图的UIViewController是UIViewController(根)的子级。我希望在子视图控制器(容器视图)上按下一个按钮,并将该事件冒泡到父视图(根UIViewController)。在AS3中,我会有这样的东西 根类创建子类 var childClass = new ChildClass() childCla

我来自as AS3的背景,所以我可以更容易地向您展示我试图用AS3做什么。我有一个UIViewController(根),里面有一个ContainerView。我的印象是容器视图的UIViewController是UIViewController(根)的子级。我希望在子视图控制器(容器视图)上按下一个按钮,并将该事件冒泡到父视图(根UIViewController)。在AS3中,我会有这样的东西

根类创建子类

var childClass = new ChildClass()

childClass.addEventListener("buttonWasPressed", callThisFunction);

private function callThisFunciton(e:Event):void
{
// move the child view
TweenLite.to(childClass,1,{x:100});

}
在子类中,我有一个button函数,它将部署这个事件,该事件将冒泡到父类

dispatchEvent(new Event("buttonWasPressed", true));
我不确定如何让根VC监听该事件。因为我使用的是containerView,所以我不知道如何为那个孩子的VC建立一个出口,并倾听孩子正在做的事情。我可以控制从IB到VC的拖动,但这只是为表示容器视图的UIView创建了一个出口。当我打印一些文本时,我可以看到子视图控制器在父VC之前首先被实例化

我发现这篇文章,我认为它指向了正确的方向。

但是我得到了一个错误,很可能是因为我不确定如何在容器视图中建立从父VC到子VC的连接。我环顾四周,似乎找不到关于这个话题的太多信息

谢谢你的帮助

有两种方法:

1)使用代理协议(推荐)

a) 在子级中,创建一个委托协议,并在子级VC上创建一个可选属性,该属性将保存该委托

protocol ChildViewControllerDelegate {

}

class ChildViewController: UIViewController {

    var delegate:ChildViewControllerDelegate?
}
b) 在委托协议中,创建一个在按下按钮时将被调用的方法,并在对委托调用此方法的子级中实现一个
buttonwarpressed()
方法。(您需要使用情节提要中的按钮连接此方法)

c) 使父视图控制器符合子协议

class ParentViewController: UIViewController, ChildViewControllerDelegate {

    func childViewControllerDidPressButton(childViewController: ChildViewController) {
        // Do fun handling of child button presses!
    }
}
c) 当子进程嵌入父进程时,会运行一种特殊类型的进程,称为嵌入进程。您可以在故事板中看到它-它是连接子级和父级的线:

向情节提要中的该序列添加标识符:

在父视图控制器中为其设置一个常量:

struct Constants {
    static let embedSegue = "embedSegue"
}

class ParentViewController: UIViewController, ChildViewControllerDelegate {

    func childViewControllerDidPressButton(childViewController: ChildViewController) {
        // Do fun handling of child button presses!
    }
}
d) 然后在父视图控制器中,重写
prepareforsgue()
方法,并检查
segue.identifier
是否与设置为标识符的内容匹配。如果有,则可以通过
segue.destinationViewController
获取对子视图控制器的引用。将其转换为子视图控制器,然后可以将父视图设置为其代理:

struct Constants {
    static let embedSegue = "embedSegue"
}

class ParentViewController: UIViewController, ChildViewControllerDelegate {

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == Constants.embedSegue {
            let childViewController = segue.destinationViewController as ChildViewController
            childViewController.delegate = self
        }
    }

    func childViewControllerDidPressButton(childViewController: ChildViewController) {
        // Do fun handling of child button presses!
    }
}
e) 赢

2)使用NSNotification和NSNotificationCenter

您可以将这些事件视为类似于ActionScript事件,但是它们不会像那样在视图层次结构中自动弹出。而是通过
NSNotificationCenter
全局发送通知。我更喜欢仅当有多个对象需要侦听一个特定事件时才使用此选项


您可以在此处找到有关
NSNotification
NSNotificationCenter
的更多信息:

或者您可以使用静态变量,这可能是最简单的方法

class ParentViewController: UIViewController {

    static var instance:ParentViewController?

    override func awakeFromNib() {
        self.dynamicType.instance = self
    }

    func parentFunction() {
        print("called \(#function) in \(self.dynamicType)")
    }
}

class ChildViewController: UIViewController {
    func childFunction() {
        ParentViewController.instance?.parentFunction()
    }

    override func viewDidAppear(_ animated: Bool) {
        childFunction()
    }
}

谢谢你非常详尽的回答!如果子视图是通过编程实现的呢??segue是如何工作的?对于这个解决方案,我的func ChildViewControllerdPressButton(childViewController:childViewController){//Do fun handling of child button press!}从未收到任何消息。有什么变化吗?这是一个好的解决方案吗??从编程角度看,这会引发什么问题(如果有的话?),从几个方面来看,这通常是个坏主意。首先,将ChildViewController耦合到ParentViewController,其他人不能使用ChildViewController。第二,如果您有两个ParentViewController实例,这将不再有效,因为只有一个静态实例。
class ParentViewController: UIViewController {

    static var instance:ParentViewController?

    override func awakeFromNib() {
        self.dynamicType.instance = self
    }

    func parentFunction() {
        print("called \(#function) in \(self.dynamicType)")
    }
}

class ChildViewController: UIViewController {
    func childFunction() {
        ParentViewController.instance?.parentFunction()
    }

    override func viewDidAppear(_ animated: Bool) {
        childFunction()
    }
}