You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将嵌入ViewController的TableViewController数据传回父ViewController?

Hey, I've got a couple of solid solutions for you here—since you're dealing with a parent-child controller relationship, delegation is the most idiomatic approach in iOS, and it'll work perfectly for your case. Let's walk through it step by step, plus I'll throw in a simpler closure alternative if you prefer.

First, let's fix why your earlier attempt failed: when you instantiated a new PayViewController inside UsersTableViewController, you were creating a completely separate instance—this wasn't the same controller that's actually displaying your input fields, so setting text there had no effect on the screen. We need to communicate with the existing parent controller instead.


Solution 1: Delegation (iOS Standard Practice)

This is the cleanest, most scalable way for child-to-parent communication.

Step 1: Define a Delegate Protocol in UsersTableViewController

Add this above your UsersTableViewController class:

protocol UsersTableViewControllerDelegate: AnyObject {
    func didSelectUser(withEmail email: String)
}

Then add a weak delegate property inside the class:

class UsersTableViewController: UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
    // Add this line
    weak var delegate: UsersTableViewControllerDelegate?
    
    // ... rest of your existing code
}

Step 2: Trigger the Delegate When a Cell is Selected

Update your didSelectRowAt method to call the delegate with the selected email:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectedUser: NSDictionary
    if searchT != "" {
        selectedUser = filteredUsers[indexPath.row]!
    } else {
        selectedUser = usersArray[indexPath.row]!
    }
    
    if let userEmail = selectedUser["email"] as? String {
        // Pass the email to the parent via delegate
        delegate?.didSelectUser(withEmail: userEmail)
        // Optional: Deselect the row for better UX
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

Step 3: Implement the Delegate in PayViewController

First, update your class declaration to conform to the new protocol:

class PayViewController: UIViewController, STPAddCardViewControllerDelegate, UsersTableViewControllerDelegate {
    // ... rest of your existing code
}

Then set the delegate in viewDidLoad, and add the delegate method to handle the incoming email:

override func viewDidLoad() {
    super.viewDidLoad()
    amountLabel.text = "$ \(finalAmount)"
    myTable = self.children[0] as! UsersTableViewController
    
    // Set the delegate here
    myTable?.delegate = self
    
    self.toField.addTarget(myTable, action: #selector(UsersTableViewController.textChanges(_:)), for: .editingChanged)
}

// Implement the delegate method
func didSelectUser(withEmail email: String) {
    // Update your input field with the selected email
    forField.text = email
    // Optional: Dismiss the keyboard
    forField.resignFirstResponder()
}

Solution 2: Closure (Simpler for One-Time Communication)

If you don't need a full delegate pattern for multiple interactions, a closure is a more concise option.

Step 1: Add a Closure Property to UsersTableViewController

class UsersTableViewController: UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
    // Add this closure property
    var onUserSelected: ((String) -> Void)?
    
    // ... rest of your existing code
}

Step 2: Call the Closure When a Cell is Selected

Update didSelectRowAt:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectedUser: NSDictionary
    if searchT != "" {
        selectedUser = filteredUsers[indexPath.row]!
    } else {
        selectedUser = usersArray[indexPath.row]!
    }
    
    if let userEmail = selectedUser["email"] as? String {
        // Trigger the closure with the email
        onUserSelected?(userEmail)
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

Step 3: Assign the Closure in PayViewController

Set this up in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    amountLabel.text = "$ \(finalAmount)"
    myTable = self.children[0] as! UsersTableViewController
    
    // Assign the closure to handle the selected email
    myTable?.onUserSelected = { [weak self] email in
        self?.forField.text = email
        self?.forField.resignFirstResponder()
    }
    
    self.toField.addTarget(myTable, action: #selector(UsersTableViewController.textChanges(_:)), for: .editingChanged)
}

Both approaches will work perfectly—delegation is better if you ever need to add more communication between the controllers later, while closures are quicker for simple one-way data passes.

内容的提问来源于stack exchange,提问作者Jose Luis Montalvo Ferreiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:31:51