Swift 3从Core Data取值问题:传值后标签未显示
Hey there! Let's break down why your labels aren't updating even though you're seeing the success popup. Sounds like the data is saving somewhere, but the handoff to WorkoutViewController isn't working as expected. Let's go through actionable fixes step by step:
1. First, Verify Your Segue Setup
Since you're navigating back to WorkoutViewController, you should be using an unwind segue (not a standard push/present segue). Here's how to confirm:
- In your Storyboard, check that the segue from
SetRepsViewControllertoWorkoutViewControllerhas a clear identifier (e.g.,"unwindToWorkoutVC"). - Ensure
WorkoutViewControllerhas an unwind action method (this is required for unwind segues to work):@IBAction func unwindToWorkoutVC(_ segue: UIStoryboardSegue) { // We'll use this to receive data later }
2. Fix the Data Passing in prepare(for:sender:)
Your suspicion about targetLog?.setAndrep?.sets failing is spot-on—optional chains fail silently if any link is nil. Let's harden this code:
In SetRepsViewController.swift:
// First, store your input values in local properties (e.g., after validating text fields) var inputSets: Int = 0 var inputReps: Int = 0 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard segue.identifier == "unwindToWorkoutVC" else { return } // Get a reference to the target view controller guard let workoutVC = segue.destination as? WorkoutViewController else { print("Failed to cast destination to WorkoutViewController") return } // Debug prints to track where the chain breaks print("Input Sets: \(inputSets)") print("WorkoutVC targetLog exists: \(workoutVC.targetLog != nil)") print("WorkoutVC setAndrep exists: \(workoutVC.targetLog?.setAndrep != nil)") // Fix optional nil issues by initializing objects if needed if workoutVC.targetLog == nil { workoutVC.targetLog = Log() // Replace with your actual Log class init } if workoutVC.targetLog?.setAndrep == nil { workoutVC.targetLog?.setAndrep = SetRep() // Replace with your SetRep class init } // Now safely assign values workoutVC.targetLog?.setAndrep?.sets = inputSets workoutVC.targetLog?.setAndrep?.reps = inputReps }
3. Update the UI at the Right Time
Even if data passes successfully, WorkoutViewController won't auto-refresh its labels. You need to update them when the view reappears:
In WorkoutViewController.swift:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Refresh labels with the latest data if let sets = targetLog?.setAndrep?.sets { yourSetsLabel.text = "Sets: \(sets)" } if let reps = targetLog?.setAndrep?.reps { yourRepsLabel.text = "Reps: \(reps)" } }
Alternatively, you can update the UI directly in the unwind action method we added earlier:
@IBAction func unwindToWorkoutVC(_ segue: UIStoryboardSegue) { guard let setRepsVC = segue.source as? SetRepsViewController else { return } // Assign and update UI in one step targetLog?.setAndrep?.sets = setRepsVC.inputSets targetLog?.setAndrep?.reps = setRepsVC.inputReps yourSetsLabel.text = "Sets: \(setRepsVC.inputSets)" yourRepsLabel.text = "Reps: \(setRepsVC.inputReps)" }
4. Double-Check Your Save Button Logic
Make sure your save button triggers the segue (not just dismisses the VC):
@IBAction func saveButtonTapped(_ sender: UIButton) { // Validate input first guard let setsText = setsTextField.text, let sets = Int(setsText), sets > 0 else { // Show error for invalid sets input return } guard let repsText = repsTextField.text, let reps = Int(repsText), reps > 0 else { // Show error for invalid reps input return } // Store validated values inputSets = sets inputReps = reps // Trigger the segue to pass data back performSegue(withIdentifier: "unwindToWorkoutVC", sender: self) // Show success popup let alert = UIAlertController(title: "Success", message: "Data saved!", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) }
Most Likely Culprits to Prioritize
- Nil optional values: If
targetLogorsetAndrephasn't been initialized, the optional chain will fail silently. The debug prints in step 2 will reveal this. - UI not refreshed: Forgetting to update labels in
viewWillAppearis a common mistake—viewDidLoaddoesn't run again when you navigate back. - Incorrect segue type: Using a push/present segue instead of an unwind will create a new instance of
WorkoutViewControllerinstead of updating the existing one.
内容的提问来源于stack exchange,提问作者IMan Merzaie

