在我的iOS应用中,我需要跨多个父ViewController
使用通用模式GetData
(我们称之为ViewControllers
)。 GetData
需要是可配置的(如隐藏/显示一些Views
)。 GetData
应该能够将数据返回到调用ViewController
。
根据我对网络上的SO和其他来源的阅读,以下是对我如何实施它的简化:
// ViewController.swift
import UIKit
class ViewController: UIViewController, GetDataDelegate {
// This shows the data received from GetData
@IBOutlet weak var textviewResult: UITextView!
// Call GetData with only mandatory and without optional views
@IBAction func onClickGetData(_ sender: Any) {
let getData = GetData(caller: self)
getData.display(delegate: self)
}
// Call GetData with both mandatory and optional data views
@IBAction func onClickGetDataWithOptional(_ sender: Any) {
let getData = GetData(caller: self, hasOptional: true)
getData.display(delegate: self)
}
// Delegate function to received data sent by GetData
func gotData(data1: String, data2: String!) {
textviewResult.text = "Mandatory: \(data1)"
+ (data2 != nil ? "\nOptional: \(data2!)" : "")
}
}
// GetData.swift
import UIKit
protocol GetDataDelegate {
func gotData(data1: String, data2: String!)
}
class GetData: UIViewController {
@IBOutlet weak var textfieldMandatory: UITextField!
@IBOutlet weak var textfieldOptional: UITextField!
// View with the optional views
@IBOutlet weak var stackViewOptional: UIStackView!
var delegate:GetDataDelegate?
var caller:UIViewController?
var hasOptional:Bool?
init(caller: UIViewController, hasOptional: Bool? = false) {
super.init(nibName: "GetData", bundle: nil)
self.caller = caller
self.hasOptional = hasOptional
}
func display(delegate:GetDataDelegate) {
self.delegate = delegate
let viewController = UIStoryboard(name: "GetData", bundle: nil).instantiateViewController(withIdentifier: "GetData")
viewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
viewController.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
caller?.present(viewController, animated: true, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@IBAction func onSubmit(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
delegate?.gotData(data1: textfieldMandatory.text!, data2: hasOptional! ? textfieldOptional.text! : nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Configure GetData (hide/show views)
// But hasOptional is nil!
//stackViewOptional?.isHidden = !hasOptional!
}
}
我面临以下问题:
delegate
未调用func
GetData
。GetData
views
进行更改(func
viewWillAppear
)。上述两种情况似乎都是因为members
delegate
(func
onSubmit
}和hasOptional
(func
{{ 1}})即使在初始化之后仍为viewWillAppear
。
需要做出哪些更正,还是需要采用不同的方法?
注意:以上是简化。在我的实际使用案例中,有多个视图控制器可以使用或不使用可选nil
来调用GetData
。
答案 0 :(得分:0)
我认为这可以更好地实现容器 - 您可以在一个屏幕上拥有多个视图控制器。 Dave DeLong写了关于这种方法的great articles。
答案 1 :(得分:0)
我终于按照我的要求开始工作了:
// ViewController.swift
import UIKit
class ViewController: UIViewController, GetDataDelegate {
// This shows the data received from GetData
@IBOutlet weak var textviewResult: UITextView!
// Call GetData with only mandatory and without optional views
@IBAction func onClickGetData(_ sender: Any) {
GetData.generate(caller: self)
}
// Call GetData with both mandatory and optional data views
@IBAction func onClickGetDataWithOptional(_ sender: Any) {
GetData.generate(caller: self, hasOptional: true)
}
// Delegate function to received data sent by GetData
func gotData(data1: String, data2: String!) {
textviewResult.text = "Mandatory: \(data1)"
+ (data2 != nil ? "\nOptional: \(data2!)" : "")
}
}
// GetData.swift
import UIKit
protocol GetDataDelegate {
func gotData(data1: String, data2: String!)
}
class GetData: UIViewController {
@IBOutlet weak var textfieldMandatory: UITextField!
@IBOutlet weak var textfieldOptional: UITextField!
// View with the optional views
@IBOutlet weak var stackViewOptional: UIStackView!
var delegate:GetDataDelegate?
var hasOptional:Bool?
static func generate(caller: UIViewController, hasOptional: Bool? = false) {
let getData = UIStoryboard(name: "GetData", bundle: nil).instantiateViewController(withIdentifier: "GetData") as! GetData
getData.delegate = caller as? GetDataDelegate
getData.hasOptional = hasOptional
caller.present(getData, animated: true, completion: nil)
}
@IBAction func onSubmit(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
delegate?.gotData(data1: textfieldMandatory.text!, data2: hasOptional! ? textfieldOptional.text! : nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Configure GetData (hide/show views)
stackViewOptional?.isHidden = !hasOptional!
}
}
希望这是一种正确的方法......