Swift - 使用协议和委托

时间:2016-05-15 22:02:51

标签: ios swift protocols

我是swift的新手,我现在的问题是我想在点击导航按钮后将RoutePreviewController页面的值传递回ViewController页面上显示。如下图所示,您可以看到RoutePreviewController不是直接来自ViewController。

This is my story board of the swift project on xcode

但是,我尝试在代码中使用协议和委托。

以下是我添加到ViewController(MainPage)的代码

protocol HandleSelectedPath{
    func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)])
}

在ViewController的viewDidLoad中

    let routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as! RoutePreviewController
    routePreviewPage.handleSelectedPathDelegate = self

和ViewController类之外的扩展

extension ViewController : HandleSelectedPath{
    func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)]){
        print("7687980")
        selectedPath = selectedRoute
        routeDraw()
    }
}

在RoutePreviewController中,我有协议的委派。

var handleSelectedPathDelegate: HandleSelectedPath? = nil 

和导航按钮操作

@IBAction func navigateButtonAction(sender: AnyObject) {
    handleSelectedPathDelegate?.selectedPathDraw(previewPath)
    dismissViewControllerAnimated(true, completion: nil)
    definesPresentationContext = true
}

因此,在单击“导航”按钮后,它会将我发送回ViewController页面,但不会执行协议的selectedPathDraw功能。我也试过打印一些随机字符串,但没有出现作为输出。

1 个答案:

答案 0 :(得分:0)

根据您上面的代码,RoutePreviewController的引用只存在于viewDidLoad内,您必须将其设置为属性,而不是这样:

var routePreviewPage: RoutePreviewController!

始终将delegate作为弱引用来实现避免保留周期是一种很好的做法,因此实现委托和协议的正确方法应如下所示:

protocol HandleSelectedPath: class {
   func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)])
}
  

<强> RoutePreviewController

weak var handleSelectedPathDelegate: HandleSelectedPath?

@IBAction func navigateButtonAction(sender: AnyObject) {
   handleSelectedPathDelegate?.selectedPathDraw(previewPath)
   dismissViewControllerAnimated(true, completion: nil)
   definesPresentationContext = true
}
  

viewDidLoad ViewController

routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as! RoutePreviewController
routePreviewPage.handleSelectedPathDelegate = self

我希望这对你有所帮助。