Swift - 使用协议和委托将值传回 ViewController [英] Swift - Passing value back to ViewController using protocol and delegate
问题描述
我是 swift 的新手,我现在的问题是我想在单击导航按钮后将 RoutePreviewController 页面中的值传递回 ViewController 页面上.如下图,您可以看到 RoutePreviewController 并没有直接从 ViewController 中转出.
但是,我尝试在代码中使用协议和委托.
这是我添加到 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屋!