Swift:我的委托协议方法需要在另一个视图控制器上执行
Posted
技术标签:
【中文标题】Swift:我的委托协议方法需要在另一个视图控制器上执行【英文标题】:Swift: My Delegate Protocol Methods Need to Execute on Another View Controller 【发布时间】:2014-12-27 19:27:50 【问题描述】:这是一个非常令人困惑的问题,所以我会尽力解释它。
我有视图控制器 A、B、C、D 和 E
我不确定我说的对不对,但换个说法,E 需要与 A 交谈,但 A 和 E 之间没有任何转义来设置委托。
A > B > C > D > E > A
有人告诉我,当您在 swift 中使用委托来访问视图控制器之间的数据时,您必须准备好很多东西:
-
为对象 B 定义一个委托协议。
给对象 B 一个可选的委托变量。这个变量应该很弱。
让对象 B 在感兴趣时向其委托发送消息
发生,例如用户按下取消或完成按钮,或者当它
需要一条信息。
使对象 A 符合委托协议。它应该把名字
类行中的协议并实现协议中的方法。
告诉对象 B 对象 A 现在是它的代表。
我一直在使用 prepapreforsegue 在视图控制器之间传递一个对象,因为它们从一个导航到下一个,并在它们继续通过 prepareforsegue 方法时添加到它。
在最终的视图控制器上,我有协议方法,这些方法旨在执行第一个视图控制器,但因为最后一个视图控制器与不同的视图控制器分离。问题是它应该在第一个视图控制器上执行这些方法。如果第一个视图控制器不能告诉最后一个视图控制器它是 segue,它怎么能到达它。
这里有一些简单的代码来告诉你我的问题和我的意思。
第一:
import UIKit
class FirstViewController: UITableViewController, LastViewControllerDelegate
var entry: EntryItem!
override func viewDidLoad()
super.viewDidLoad()
entry = EntryItem()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
//here's where I access the next view controller and set controller.entry and controller.delegate
let controller = segue.destinationViewController as NextViewController
controller.entry = entry
func lastViewControllerDidCancel(controller: LastViewController, didNotFinishAddingEntry draftentry: EntryItem)
//this is where I wanna do something
dismissViewControllerAnimated(true, completion: nil)
func lastViewController(controller: LastViewController, didFinishAddingEntry finalentry: EntryItem)
//this is where I wanna do something
dismissViewControllerAnimated(true, completion: nil)
下一个:
import UIKit
class Next1ViewController: UITableViewController, LastViewControllerDelegate
var entry: EntryItem!
override func viewDidLoad()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
//here's where I access the next view controller and set controller.entry and controller.delegate
let controller = segue.destinationViewController as Next2ViewController
controller.entry = entry
接下来 2:
import UIKit
class Next2ViewController: UITableViewController, LastViewControllerDelegate
var entry: EntryItem!
override func viewDidLoad()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
//here's where I access the next view controller and set controller.entry and controller.delegate
let controller = segue.destinationViewController as LastViewController
controller.entry = entry
controller.delegate = ???? //Not self, but needs to be the first one.
最后:
import UIKit
protocol LastViewControllerDelegate: class
func lastViewControllerDidCancel(controller: LastViewController, didNotFinishAddingEntry draftentry: EntryItem)
func lastViewController(controller: LastViewController, didFinishAddingEntry finalentry: EntryItem)
class LastViewController: UITableViewController
weak var delegate: LastViewControllerDelegate?
var entry: EntryItem!
override func viewDidLoad()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
...
@IBAction func cancel()
delegate?.lastViewControllerDidCancel(self, didNotFinishAddingEntry: entry)
@IBAction func done()
//do some final additions to entry object
delegate?.lastViewController(self, didFinishAddingEntry: entry)
【问题讨论】:
能否修改NextViewController
中的prepareForSegue
代码以设置controller.delegate = self.delegate
?因为 self.delegate 引用了 FirstViewController,所以应该在 FirstViewController 上调用方法。
@pbasdf 我想我在您输入此评论时输入了我的答案!那时我们可能肯定是对的。
@jrturton 我认为它会起作用,但是对于 5 个 VC,你建议使用通知可能是更好的做法。
真的吗?等一下再看一遍帖子,希望我编辑它以减少混乱。唯一需要就位的代表是在第一个和最后一个之间,而不是在第一个和第二个或第二个和第三个之间。不确定这是否重要。
在我的答案中添加了一个部分进行解释。如果中间 vc 对委托没有用处,请使用通知。
【参考方案1】:
你不能让你的第一个视图控制器符合所有的委托协议(或者,可能,制作一个单一的委托协议,否则你会遇到转换问题),然后不要这样做:
controller.delegate = self
做事
controller.delegate = self.delegate
或者,如果您已经删除了几个步骤,则使用通知通常比委派更好。如果中间的视图控制器除了转发之外没有其他目的,您应该使用通知。
【讨论】:
是的,这行不通,我试过了。这只有在实际上只有 3 个视图控制器时才有效,这只是一个示例,但我会在帖子中修复它,因为这很令人困惑,抱歉。还有更多。有第一,第二,第三,第四,第五,最后。 在这种情况下,一定要使用通知。 我将不得不查找通知,我不确定在这种情况下这些是什么,但是谢谢,如果这有效,我会告诉你。 是的,我在通知中找不到任何内容,我不明白你的意思。我听说过通知的唯一上下文是推送通知。 @Sephethus 我今天也遇到了这个问题...发现这个 SO 问题,最后一个答案对 NSNotificationCenter 有很大帮助...***.com/questions/24049020/…以上是关于Swift:我的委托协议方法需要在另一个视图控制器上执行的主要内容,如果未能解决你的问题,请参考以下文章