跨屏幕收集数据的更快捷,更清晰的方式

时间:2018-04-16 09:17:55

标签: ios swift xcode

我有多个屏幕,其中有textfield(s)。当用户在每个屏幕上下一个时,我想从他们那里收集数据。我试过的是:

MyViewController:

class MyViewController: UIViewController {

@IBOutlet weak var textField: UITextField!

var foo: MyModel = MyModel() // create instance of the model for the first time

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is AnotherViewController {
        self.foo.column1 = textField.text ?? "" // update column1

        let vc = segue.destination as? AnotherViewController
        vc?.foo = self.foo // here, im passing the updated model
    }
}
}

AnotherViewController:

class AnotherViewController: UIViewController {

@IBOutlet weak var textField: UITextField!

var foo: MyModel! // model is constructed already, and passed with the updated data

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is AnotherAgainViewController {
        self.foo.column2 = textField.text ?? "" // update column2

        let vc = segue.destination as? AnotherAgainViewController
        vc?.foo = self.foo // im passing again the updated model
    }
}
}

然后基本上,我一遍又一遍地重复这段代码。这在可维护性和灵活性方面是否可以?或者有更好的方法吗?

PS :我不想仅使用单例来实现数据共享,因为这不是一个好习惯,难以调试(特别是当有人修改它时),并且会导致意大利面条代码。我希望以更清洁和可维护的方式实现这一目标。

2 个答案:

答案 0 :(得分:2)

使用基本控制器类并覆盖performSegueWithIdentifier

class BaseController: UIViewController {

var foo: MyModel! // model is constructed already, and passed with the updated data

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is AnotherAgainViewController {  // Replace if else by switch if you have many VC's
        let vc = segue.destination as? AnotherAgainViewController
        vc?.foo = self.foo
    }
}
} 

现在在 MyViewController

class MyViewController: BaseController {

//
..
//  

// Wherever you are setting model  

self.foo = localModel    // self.foo is of BaseController

}  

与其他ViewControllers类似。

答案 1 :(得分:1)

通过对@Nitish代码的一些修改来管理:

<强> BaseController:

class BaseController: UIViewController {

var foo: MyModel!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.destination is BaseController {
        let vc = segue.destination as? BaseController
        vc?.foo = self.foo
    }
}
}

<强> MyViewController:

class MyViewController: BaseController {

    @IBOutlet weak var textField: UITextField!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        self.foo = Foo() // call initialization only on the first screen
        self.foo.column1 = foo.text ?? "" // update column1            
        super.prepare(for: segue, sender: sender) // call the super, and also this is flexible because I don't call specific view controller here.
    }
}

<强> AnotherViewController:

class AnotherViewController: BaseController {

    @IBOutlet weak var textField: UITextField!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        self.foo.column2 = foo.text ?? "" // update column2            
        super.prepare(for: segue, sender: sender)
    }
}