Swift 4中如何在多ViewController间传递TextField值完成注册?
Hey there! Let's work through getting those text field values from your first ViewController to the third one for the registration request. I'll walk you through two reliable approaches that should fix your issue.
Approach 1: Pass Values Through the Second ViewController (Most Straightforward)
Since you're navigating from VC1 → VC2 → VC3, you can pass the data step-by-step through each intermediate view controller.
First, update your first VC's button tap handler to safely capture and pass values to VC2:
@IBAction func nextButtonTapped(_ sender: Any) { // Safely unwrap and validate text field values (no force unwrapping!) guard let userName = nameTextfield.text, !userName.isEmpty, let userPhone = phoneTextfield.text, !userPhone.isEmpty else { // Add an error alert here to tell users to fill in all fields return } // Push to your second view controller (adjust the storyboard ID as needed) if let secondVC = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController { // Pass values to VC2 secondVC.tempUserName = userName secondVC.tempUserPhone = userPhone navigationController?.pushViewController(secondVC, animated: true) } }
Next, add properties to your second ViewController to hold the temporary values:
class SecondViewController: UIViewController { // Temp storage for user data var tempUserName: String? var tempUserPhone: String? // ... rest of your VC2 code // When navigating to VC3, pass the values along @IBAction func goToThirdVCTapped(_ sender: Any) { guard let name = tempUserName, let phone = tempUserPhone else { return } if let thirdVC = storyboard?.instantiateViewController(withIdentifier: "ThirdViewController") as? ThirdViewController { thirdVC.registerParams = ["name": name, "phone": phone] navigationController?.pushViewController(thirdVC, animated: true) } } }
Finally, update your third ViewController to receive and use the parameters:
class ThirdViewController: UIViewController { // Property to hold the passed parameters var registerParams: Parameters? @IBAction func registerButtonTapped(_ sender: Any) { // Make sure we have valid parameters before sending the request guard let parameters = registerParams else { // Handle missing data (show alert, log error) return } // Send your Alamofire request with the passed parameters Alamofire.request(URL_USER_REGISTER, method: .post, parameters: parameters).responseJSON { response in print(response) if let result = response.result.value as? NSDictionary { // self.labelMessage.text = result["message"] as? String } } } }
Approach 2: Use a Singleton for Temporary Storage (Great for Cross-VC Data)
If you don't want to pass data through every intermediate VC, a singleton class can temporarily hold the user's input until you're ready to use it.
First, create a singleton manager class:
class UserRegistrationTempStore { // Singleton instance (only one exists in the app) static let shared = UserRegistrationTempStore() private init() {} // Prevent others from creating new instances // Temp storage for user data var userName: String? var userPhone: String? // Clear data after registration to avoid leftover values func reset() { userName = nil userPhone = nil } }
Update your first VC's button handler to save values to the singleton:
@IBAction func nextButtonTapped(_ sender: Any) { guard let userName = nameTextfield.text, !userName.isEmpty, let userPhone = phoneTextfield.text, !userPhone.isEmpty else { // Show error alert for empty fields return } // Save values to the singleton UserRegistrationTempStore.shared.userName = userName UserRegistrationTempStore.shared.userPhone = userPhone // Navigate to VC2 as usual }
Then use the data in your third VC's registration handler:
@IBAction func registerButtonTapped(_ sender: Any) { guard let name = UserRegistrationTempStore.shared.userName, let phone = UserRegistrationTempStore.shared.userPhone else { // Handle missing data return } let parameters: Parameters = ["name": name, "phone": phone] Alamofire.request(URL_USER_REGISTER, method: .post, parameters: parameters).responseJSON { response in print(response) if let result = response.result.value as? NSDictionary { // self.labelMessage.text = result["message"] as? String } // Clear the temp data after registration UserRegistrationTempStore.shared.reset() } }
Key Notes to Avoid Crashes
- Never force-unwrap text fields: Use
guard letorif letto safely handle empty or nil values (force unwrapping!will crash your app if the text field is empty). - If you're using segues instead of direct instantiation, pass data in the
prepare(for:sender:)method of each VC instead of the button tap handler. - Avoid using
UserDefaultsfor sensitive data like phone numbers—singletons are stored in memory and cleared after use, which is safer.
内容的提问来源于stack exchange,提问作者user9606399

