ViewController将Swift从一个VC推到另一个VC并返回

时间:2018-10-05 12:59:06

标签: ios swift uiviewcontroller

考虑两个视图控制器Controller1Controller2,我在控制器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)
   }

3 个答案:

答案 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的委托,则测试将在运行时强制错误。