从非父级View Controller分配委托

时间:2018-09-18 13:55:50

标签: swift delegates swift-protocols

我在Swift 4中的协议和委托方面有些挣扎。我将尽我所能描述/展示我的财产。

主视图控制器:(MVC) 1.我有Main Viewcontroller类(MVC)。 VC具有我想从另一个ViewController类(AVC)访问的选项的属性

class ViewController: UIViewController {
var options: Options?


 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if (segue.identifier == "To Statements") {
        // pass data to next view
        let vc = segue.destination
        let statementVC = vc as! StatementsViewController
        statementVC.coreDataStack = coreDataStack
        statementVC.currentPerson = currentPerson

    }
}

extension ViewController: FormateStatementDelegate {

   // formatting protocol
   func addStatementFormat() -> Int {
     // here is where I would use the options var that is found in the (MVC)
   }
}

Statement ViewController:(SVC) 2.我有一个从(MVC)调用的View Controller类Statement ViewController(SVC)。我正在使用为segue func准备将此视图控制器设置为(MVC)。

    class StatementsViewController: UIViewController{

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if (segue.identifier == "Add Statement") {
        // pass data to next view
        //print("segue to add statement")
        let vc = segue.destination
        let addStatementVC = vc as! AddStatementViewController
        addStatementVC.coreDataStack = coreDataStack
        addStatementVC.personName = currentPerson!.name!    
    }
    }

AddStatement视图控制器(AVC) 3.我有第三个视图控制器类AddStatement View Controller(AVC),它是从(SVC)调用的。我也正在使用prese for segue func来通过(SVC)设置此视图控制器。

此类具有我在(MVC)中定义的协议。

protocol FormateStatementDelegate {
func  func addStatementFormat() -> Intmal
}

class AddStatementViewController: UIViewController{
   var delegate FormateStatementDelegate! = nil
}

我很困惑的地方是在哪里设置委托属性。我看到的示例似乎是在准备seguer func时设置了proxy属性。但是,由于(MVC)是符合FormateStatementDelegate协议的协议,由于它们没有父/子关系,因此在哪里以及如何在(AVC)中设置委托。我希望我已经以有意义的方式对此进行了解释。

1 个答案:

答案 0 :(得分:0)

您的委托被声明为隐式展开的可选:

class AddStatementViewController: UIViewController{
   var delegate FormateStatementDelegate! = nil
}

请注意这一点。如果您忘记设置委托,应用程序将崩溃。 strong retention cycle也有可能导致内存泄漏。我使用的一般模式是将其声明为弱可选项:

protocol FormateStatementDelegate: class {
    ...
}

class AddStatementViewController: UIViewController{
    weak var delegate: FormateStatementDelegate?

    func doSomething() {
        delegate?.addStatementFormat() // This statement will do nothing if delegate is nil
    }
}

现在继续您的问题:如果我正确理解了您的问题描述,则排序顺序如下:

ViewContorller -> StatementViewController -> AddStatementViewController

AddStatementViewController有一个委托,ViewController符合。您只需要在第二个视图控制器中保存对MainViewController实例的引用:

class ViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
        if (segue.identifier == "To Statements") {
            // pass data to next view
            let vc = segue.destination
            let statementVC = vc as! StatementsViewController
            statementVC.coreDataStack = coreDataStack
            statementVC.currentPerson = currentPerson
            statementVC.formateStatementDelegate = self
        }
    }
}

class StatementViewController {
    weak var formateStatementDelegate: FormateStatementDelegate?

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier == "Add Statement") {
            // pass data to next view
            //print("segue to add statement")
            let vc = segue.destination
            let addStatementVC = vc as! AddStatementViewController
            addStatementVC.coreDataStack = coreDataStack
            addStatementVC.personName = currentPerson!.name!    
            addStatementVC.delegate = formateStatementDelegate
        }
    }
}