点击按钮将AddFoodViewController食材数组添加至ListViewController的TableView
Hey there! You're already doing great getting your ListViewController up and running as a new iOS dev. Let's work through getting that ingredient array from AddFoodViewController over to your shopping list. I'll walk you through two common, easy-to-implement solutions—starting with the one that fits best with your existing code.
Solution 1: Use Segues (Matches Your Current Setup)
First, let's fix a couple of small issues in your code, then wire up the data transfer properly:
Step 1: Update ListViewController to Receive the Array
Make sure your ListViewController has a variable that can hold the incoming array (your original code tried assigning an array to a String variable, which won't work!). Add this to ListViewController:
class ListViewController: UIViewController { // This will hold the ingredients sent from AddFoodVC var incomingFoodItems: [String] = [] // Your existing code for the shopping list table view... }
Step 2: Fix AddFoodViewController Code
Let's clean up your AddFoodVC and add the logic to trigger the segue and pass the data:
class AddFoodViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{ @IBOutlet weak var FoodTableView: UITableView! @IBOutlet weak var sendFoodBtn: UIButton! // Your ingredient array let array = ["1 Salad", "3oz Chicken", "2 Tomatoes", "2 Cucumbers"] override func viewDidLoad() { super.viewDidLoad() // Don't forget to set the table view's data source/delegate! FoodTableView.dataSource = self FoodTableView.delegate = self } // Updated table view section count method (modern syntax) func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return array.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // Use dequeueReusableCell instead of creating a new cell every time (better performance!) let foodCell = tableView.dequeueReusableCell(withIdentifier: "foodCell", for: indexPath) foodCell.textLabel?.text = array[indexPath.row] foodCell.backgroundColor = .clear foodCell.textLabel?.textColor = .darkGray foodCell.textLabel?.font = UIFont(name: foodCell.textLabel?.font.fontName ?? "System", size:17) return foodCell } // Trigger the segue when the "Add to List" button is tapped @IBAction func addOnClick(_ sender: Any) { performSegue(withIdentifier: "toList", sender: self) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "toList" { // Safely cast the destination VC to ListViewController guard let listVC = segue.destination as? ListViewController else { return } // Pass your ingredient array to the ListVC's variable listVC.incomingFoodItems = array } } }
Step 3: Use the Array in ListViewController
Once the data is passed, add it to your shopping list and refresh the table view. Add this to ListViewController's viewDidLoad() (or wherever you handle updating the list):
override func viewDidLoad() { super.viewDidLoad() // Assume your shopping list array is called shoppingListArray shoppingListArray.append(contentsOf: incomingFoodItems) // Refresh the table view to show the new items tableView.reloadData() }
Solution 2: Use a Closure (Great for Modal Presentations)
If you're presenting AddFoodViewController modally (instead of pushing it via navigation), a closure is a more flexible approach that doesn't rely on segues:
Step 1: Add a Closure to AddFoodViewController
Add a closure property that will "hand off" the array when the button is tapped:
class AddFoodViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{ // Closure to pass the food array back to ListVC var onFoodAdded: (([String]) -> Void)? // Your existing code... @IBAction func addOnClick(_ sender: Any) { // Pass the array through the closure onFoodAdded?(array) // Close the AddFoodVC dismiss(animated: true) } }
Step 2: Set Up the Closure in ListViewController
When you present AddFoodViewController from ListVC, set the closure to handle the incoming array:
// Example: Button action in ListVC to open AddFoodVC @IBAction func openAddFoodVC(_ sender: Any) { guard let addFoodVC = storyboard?.instantiateViewController(withIdentifier: "AddFoodViewController") as? AddFoodViewController else { return } // Set the closure to receive the array addFoodVC.onFoodAdded = { [weak self] foodItems in // Add the new items to your shopping list self?.shoppingListArray.append(contentsOf: foodItems) // Refresh the table view self?.tableView.reloadData() } // Present the AddFoodVC modally present(addFoodVC, animated: true) }
Quick Notes to Remember
- Double-check that your segue identifier in Storyboard is exactly
toList(case-sensitive!) - Using
dequeueReusableCellis a best practice—it reuses table view cells instead of creating new ones, which makes your app smoother - When using closures, always use
[weak self]to avoid memory leaks
内容的提问来源于stack exchange,提问作者Laura94

