ViewController 将 Swift 从一个 VC 推送到另一个 VC 并返回
Posted
技术标签:
【中文标题】ViewController 将 Swift 从一个 VC 推送到另一个 VC 并返回【英文标题】:ViewController Pushing Swift From One VC to Another VC And Returning back 【发布时间】:2018-10-05 12:59:06 【问题描述】:考虑两个视图控制器 Controller1
和 Controller2
,我在控制器 1 中创建了许多 UITextField
的表单,当用户单击特定的 UITextField
时,它会移动到 Controller2 并选择那里的数据.
选择Controller2
中的数据后,它会自动移动到Controller1
,而从控制器2返回控制器1时,其他UITextfield
数据被清除,只找到控制器2中选择的数据。选择后我需要在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)
【问题讨论】:
添加您的 VC1 代码以及如何从 VC2 弹出到 VC1 @Anbu.karthik 我的 VC1 代码让 storyBoard: UIStoryboard = UIStoryboard(name: "NewUserLogin", bundle: nil) let newViewController = storyBoard.instantiateViewController(withIdentifier: "ComplexList") as! ComplexSearchViewController self.present(newViewController, animated: true, completion: nil) 您可能想要使用展开转场。请看***.com/questions/35313747/… 仅找到来自 controller2 的选定数据 - 您如何将数据从 controller2 获取到 controller1? 【参考方案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)
【讨论】:
【参考方案2】: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")
【讨论】:
这很好地解释了如何push/pop,但没有说明在VC2上输入的数据将如何返回到VC1中显示。【参考方案3】:有几种方法可以做到这一点,但这通常取决于您如何从 VC#1 移动到 VC#2 并返回。
(1) 您发布的代码意味着您有一个带有两个视图控制器的故事板。在这种情况下,创建从 VC#1 到 VC#2 的转场和“展开”转场。两者都相当容易做到。 cmets 中提供的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 的 整个 实例,因此可以访问未标记为 private
的所有内容。
(2) 如果您要从 VC#1 呈现/关闭 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 的委托,您的测试将在运行时强制出错。
【讨论】:
以上是关于ViewController 将 Swift 从一个 VC 推送到另一个 VC 并返回的主要内容,如果未能解决你的问题,请参考以下文章
swift3:如何将 xib 呈现给 viewcontroller
将 ViewController 缩小为圆形过渡 - swift
如何将计时器中的数据传递给新的 ViewController (Swift 3)
如何将值从 SceneDelegate 文件传输到 ViewController (Swift 5)