Swift - 使用协议和委托将值传回 ViewController [英] Swift - Passing value back to ViewController using protocol and delegate

查看:46
本文介绍了Swift - 使用协议和委托将值传回 ViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 swift 的新手,我现在的问题是我想在单击导航按钮后将 RoutePreviewController 页面中的值传递回 ViewController 页面上.如下图,您可以看到 RoutePreviewController 并没有直接从 ViewController 中转出.

这是我在 xcode 上的 swift 项目的故事板

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

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

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

在ViewController的viewDidLoad中

 let routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as!路由预览控制器routePreviewPage.handleSelectedPathDelegate = self

以及 ViewController 类之外的扩展

extension ViewController : HandleSelectedPath{func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)]){打印(7687980")selectedPath = selectedRoute路线绘制()}}

在 RoutePreviewController 中,我有协议的委托.

var handleSelectedPathDelegate: HandleSelectedPath?= 零

和导航按钮操作

@IBAction func navigateButtonAction(sender: AnyObject) {handleSelectedPathDelegate?.selectedPathDraw(previewPath)解雇视图控制器动画(真,完成:零)定义PresentationContext = true}

因此,在单击Navigate 按钮后,它确实将我送回了ViewController 页面,但没有执行协议的selectedPathDraw 功能.我也尝试打印一些随机字符串,但没有任何输出.

解决方案

根据你上面的代码对你的 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)解雇视图控制器动画(真,完成:零)定义PresentationContext = true}

<块引用>

viewDidLoad 的 ViewController:

routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as!路由预览控制器routePreviewPage.handleSelectedPathDelegate = self

希望对您有所帮助.

I'm new to swift and my problem right now is I want to pass the value from RoutePreviewController page back to display on ViewController page after clicking on the Navigate Button. As below picture, you can see that the RoutePreviewController is not directly segue from the ViewController.

This is my story board of the swift project on xcode

However, I tried using protocol and delegate in the code.

Here are codes that I have add to the ViewController (MainPage)

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

in viewDidLoad of ViewController

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

and an extension outside the ViewController class

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

And in RoutePreviewController, I have delegation of the protocol.

var handleSelectedPathDelegate: HandleSelectedPath? = nil 

and the Navigate button action

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

As a result, after clicking the Navigate button, it does send me back to the ViewController page but the selectedPathDraw function of the protocol is not performed. I also tried printing some random string but nothing came up as an output.

解决方案

The reference for your RoutePreviewController according to your code above only exist inside your viewDidLoad, you have to set as property instead like this:

var routePreviewPage: RoutePreviewController!

Always it's a good practice implement your delegate as a weak reference to avoid retain-cycles, so the correct way of implement your delegate and protocol should be as the following code:

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 of ViewController:

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

I hope this help you.

这篇关于Swift - 使用协议和委托将值传回 ViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆