Swift:我的代理协议方法需要在另一个视图控制器上执行

时间:2014-12-27 19:27:50

标签: ios iphone swift delegates

这是一个非常令人困惑的问题,所以我会尽力解释它。

我有视图控制器A,B,C,D和E

我不确定我是否说得对,但重新说明一下,E需要与A交谈,但A和E之间没有设置委托的区别。

A> B> C> D> E>甲

有人告诉我,当你在swift中使用代理来访问视图控制器之间的数据时,你必须有很多东西:

  1. 为对象B定义委托协议。
  2. 为对象B提供可选的委托变量。这个变量应该很弱。
  3. 当有趣的事情时,让对象B向其委托发送消息 发生,例如用户按下取消或完成按钮,或者当它 需要一条信息。
  4. 使对象A符合委托协议。应该把它的名字 该类协议在其类行中实现协议中的方法。
  5. 告诉对象B对象A现在是其委托。
  6. 我一直在使用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)
    }
    
    }
    

1 个答案:

答案 0 :(得分:2)

难道你不能让你的第一个视图控制器符合所有委托协议(或者,可能会制作一个委托协议,否则你会遇到转换问题),然后不要这样做:

controller.delegate = self

只做

controller.delegate = self.delegate

或者,如果您删除了几个步骤,则使用通知通常比委派更好。如果介入视图控制器除了转发它之外没有委托的目的,您应该使用通知。