【问题标题】:ViewController Pushing Swift From One VC to Another VC And Returning backViewController 将 Swift 从一个 VC 推送到另一个 VC 并返回
【发布时间】: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)
  • 您可能想要使用展开转场。请看stackoverflow.com/questions/35313747/…
  • 仅找到来自 controller2 的选定数据 - 您如何将数据从 controller2 获取到 controller1?

标签: ios swift uiviewcontroller


【解决方案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 的委托,您的测试将在运行时强制出错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-15
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多