考虑两个视图控制器Controller1
和Controller2
,我在控制器1中创建了许多UITextField
的形式,因为当用户单击特定的UITextField
时,它会移动到Controller2,然后他在那里选择数据。
在Controller2
中选择数据后,它会自动移至Controller1
,同时从controller2返回到controller1的其他UITextfield
数据被清除,仅从controller2中找到选定的数据。选择后,我需要在UITextfield
中找到所有数据。
这是从Controller2
返回到Controller1
的代码
if(Constants.SelectedComplexName != nil)
{
let storyBoard: UIStoryboard = UIStoryboard(name: "NewUserLogin", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewUser") as! NewUserRegistrationViewController
self.present(newViewController, animated: true, completion: nil)
}
答案 0 :(得分:1)
要传递消息,您需要实现Delegate
。
protocol SecondViewControllerDelegate: NSObjectProtocol {
func didUpdateData(controller: SecondViewController, data: YourDataModel)
}
//This is your Data Model and suppose it contain 'name', 'email', 'phoneNumber'
class YourDataModel: NSObject {
var name: String? //
var phoneNumber: String?
var email: String?
}
class FirstViewController: UIViewController, SecondViewControllerDelegate {
var data: YourDataModel?
var nameTextField: UITextField?
var phoneNumberTextField: UITextField?
var emailTextField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
callWebApi()
}
func callWebApi() {
//After Success Fully Getting Data From Api
//Set this data to your global object and then call setDataToTextField()
//self.data = apiResponseData
self.setDataToTextField()
}
func setDataToTextField() {
self.nameTextField?.text = data?.name
self.phoneNumberTextField?.text = data?.phoneNumber
self.emailTextField?.text = data?.email
}
func openNextScreen() {
let vc2 = SecondViewController()//Or initialize it from storyboard.instantiate method
vc2.delegate = self//tell second vc to call didUpdateData of this class.
self.navigationController?.pushViewController(vc2, animated: true)
}
//This didUpdateData method will call automatically from second view controller when the data is change
func didUpdateData(controller: SecondViewController, data: YourDataModel) {
}
}
class SecondViewController: UIViewController {
var delegate: SecondViewControllerDelegate?
func setThisData(d: YourDataModel) {
self.navigationController?.popViewController(animated: true)
//Right After Going Back tell your previous screen that data is updated.
//To do this you need to call didUpdate method from the delegate object.
if let del = self.delegate {
del.didUpdateData(controller: self, data: d)
}
}
}
答案 1 :(得分:0)
push your view controller instead of a present like this
if(Constants.SelectedComplexName != nil)
{
let storyBoard: UIStoryboard = UIStoryboard(name: "NewUserLogin", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewUser") as! NewUserRegistrationViewController
self.navigationController?.pushViewController(newViewController, animated: true)
}
,然后从vc2这样选择数据后弹出
self.navigationController?.popViewController(animated: true)
,如果您不使用导航控制器,则只需调用Dismiss
方法
self.dismiss(animated: true) {
print("updaae your data")
}
答案 2 :(得分:0)
有几种方法可以做到这一点,但这通常取决于您如何从VC#1迁移到VC#2,然后再返回。
(1)您发布的代码意味着您拥有一个带有两个视图控制器的情节提要。在这种情况下,请创建从VC#1到VC#2的序列,然后“展开”序列。两者都很容易做到。注释中提供的link可以很好地显示您,但是取决于(1)您希望将多少数据传递回VC#1和(2)您是否希望在VC上执行功能#2,您也可以这样做:
VC#1:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowVC2" {
if let vc = segue.destination as? VC2ViewController {
vc.VC1 = self
}
}
}
VC#2:
weak var VC1:VC1ViewController!
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isMovingFromParentViewController {
VC1.executeSomeFunction()
}
}
基本上,您正在传递VC1的 entire 实例,因此可以访问未标记为private
的所有内容。
(2)如果要从VC#1提供VC#2或从其中删除VC#2,请使用delegate
样式,如答案之一所述。
VC#1:
var VC2 = VC2ViewController()
extension VC1ViewController: VC2ControlllerDelegate {
func showVC2() {
VC2.delegate = self
VC2.someData = someData
present(VC2, animated: true, completion: nil)
}
function somethingChanged(sender: VC2ViewController) {
// you'll find your data in sender.someData, do what you need
}
}
VC#2:
protocol VC2Delegate {
func somethingChanged(sender: VC2ViewController) {
delegate.somethingChanged(sender: self)
}
}
class DefineViewController: UIViewController {
var delegate:DefineVCDelegate! = nil
var someData:Any!
func dismissMe() {
delegate.somethingChanged(sender: self)
dismiss(animated: true, completion: nil)
}
}
}
基本上,您使VC#1成为VC2的委托。我更喜欢VC#2中的`delegate'声明语法,因为如果忘记将VC#1设置为VC#2的委托,则测试将在运行时强制错误。