在swift中将调度事件发送到父ViewController

时间:2015-03-27 05:37:12

标签: xcode actionscript-3 swift uiview uicontainerview

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

Root Class创建子类

var childClass = new ChildClass()

childClass.addEventListener("buttonWasPressed", callThisFunction);

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

}

在Child Class中,我有一个按钮功能,可以部署这个会冒泡到父母的事件。

dispatchEvent(new Event("buttonWasPressed", true));

我不确定该怎么做才能让根VC监听该事件。因为我使用的是一个容器视图,所以我不知道如何设置这个孩子VC的插座并听取孩子正在做的事情。我可以控制从IB到VC的拖动,但这只是为代表容器视图的UIView创建了一个插座。当我打印一些文本时,我可以看到子视图控制器首先在父VC之前被实例化。

我发现这篇帖子我认为指向了正确的方向。 https://craiggrummitt.wordpress.com/2014/07/14/communication-between-objects-in-objective-c-and-swift-compared-with-actionscript-part-5/

但我收到错误,很可能是因为我不确定如何在容器视图中建立从父VC到子VC的连接。我环顾四周,似乎无法找到有关该主题的更多信息。

感谢您的帮助!

2 个答案:

答案 0 :(得分:32)

有两种方法:

1)使用委托协议(推荐)

a)在您的孩子中,在子VC上创建一个委托协议和一个可选属性来保存该委托。

protocol ChildViewControllerDelegate {

}

class ChildViewController: UIViewController {

    var delegate:ChildViewControllerDelegate?
}

b)在委托协议中创建一个按下按钮时将被调用的方法,并在子代上实现buttonWasPressed()方法,该方法在委托上调用此方法。 (您将要使用故事板中的按钮连接此方法)

protocol ChildViewControllerDelegate {
    func childViewControllerDidPressButton(childViewController:ChildViewController)
}

class ChildViewController: UIViewController {

    var delegate:ChildViewControllerDelegate?

    @IBOutlet weak var button: UIButton!

    @IBAction func buttonWasPressed(sender: AnyObject) {
        self.delegate?.childViewControllerDidPressButton(self)
    }
}

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

class ParentViewController: UIViewController, ChildViewControllerDelegate {

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

c)当孩子嵌入父母时,会运行一种称为嵌入segue的特殊segue。您可以在故事板中看到它 - 它是将孩子连接到父母的线:

shows the embed segue selected

在故事板中为该segue添加标识符:

shows the settings for embed segue, with the custom identifier set

父视图控制器中的常量:

struct Constants {
    static let embedSegue = "embedSegue"
}

class ParentViewController: UIViewController, ChildViewControllerDelegate {

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

d)然后在父视图控制器中,覆盖prepareForSegue()方法并检查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事件类似,但它们不会像AS那样自动在视图层次结构中冒泡。而是通过NSNotificationCenter全局调度通知。当有多个对象需要监听某个特定事件时,我更喜欢只使用它。

您可以在此处找到有关NSNotificationNSNotificationCenter的更多信息:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/

答案 1 :(得分:4)

那么你可以使用静态变量,这可能是最简单的方法。

SELECT (comments_html+fb_total+google_plus_one+pinterest+linked_in) as 'total_social', *
FROM npt_articles
WHERE <<something>>
ORDER BY 1