Swift中TableView按钮点击无法获取所有cell文本框值的问题解决
Got it, let’s break down how to fix this issue step by step—you’re hitting a classic problem with variable overwriting because you’re using single properties to track data for multiple table rows. Here’s how to refactor your code to validate every text field correctly:
1. Create a Model to Track Row-Specific Data
First, replace your standalone alertMinL, alertMaxL, and alertParam variables with a struct that encapsulates all validation rules and the input value for a single row. This keeps each row’s data grouped together:
struct RowValidationData { let alertParam: String let alertMinL: Int? let alertMaxL: Int? var inputValue: String? // Stores the text entered in the row's text field }
2. Use an Array to Store All Rows’ Data
In your view controller, declare an array of RowValidationData instead of single variables. This will hold the configuration and input for every table row:
class YourViewController: UIViewController { private var validationRows: [RowValidationData] = [] // ... rest of your existing code }
Populate this array when you parse your JSON (instead of assigning to single variables):
// Example JSON parsing logic (adjust to match your actual JSON structure) for item in jsonArray { let param = item["alertParam"] as? String ?? "" let min = item["alertMinL"] as? Int let max = item["alertMaxL"] as? Int validationRows.append(RowValidationData(alertParam: param, alertMinL: min, alertMaxL: max, inputValue: nil)) } tableView.reloadData()
3. Update Custom Cell to Track Row Inputs
Modify your table view cell to notify the view controller when its text field changes, passing along the row index so you can update the correct entry in validationRows. Here’s an example with a custom cell:
class InputValidationCell: UITableViewCell { @IBOutlet weak var inputTextField: UITextField! var rowIndex: Int? var textChangedHandler: ((Int, String?) -> Void)? override func awakeFromNib() { super.awakeFromNib() inputTextField.addTarget(self, action: #selector(textFieldDidUpdate), for: .editingChanged) } @objc private func textFieldDidUpdate(_ textField: UITextField) { guard let row = rowIndex else { return } textChangedHandler?(row, textField.text) } }
4. Bind Cell to Row Data in cellForRowAt
When dequeuing cells, link the cell to its corresponding row index and update the validationRows array whenever the text field changes:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "InputValidationCell", for: indexPath) as! InputValidationCell let rowData = validationRows[indexPath.row] // Set initial text and row index cell.inputTextField.text = rowData.inputValue cell.rowIndex = indexPath.row // Update validationRows when text changes cell.textChangedHandler = { [weak self] row, text in guard let self = self else { return } var updatedData = self.validationRows[row] updatedData.inputValue = text self.validationRows[row] = updatedData } // Optional: Set other UI elements (e.g., label for alertParam) return cell }
5. Validate All Rows in Button Tap
Now, in your button’s action method, loop through the validationRows array to check every text field against its rules:
@IBAction func validateAllInputs(_ sender: UIButton) { var isValid = true for rowData in validationRows { guard let input = rowData.inputValue, !input.isEmpty else { print("\(rowData.alertParam) cannot be empty!") isValid = false continue } // Check min value if present if let min = rowData.alertMinL, let inputInt = Int(input), inputInt < min { print("\(rowData.alertParam) must be at least \(min)!") isValid = false } // Check max value if present if let max = rowData.alertMaxL, let inputInt = Int(input), inputInt > max { print("\(rowData.alertParam) cannot exceed \(max)!") isValid = false } } if isValid { // All inputs passed validation—proceed with your logic print("All inputs are valid!") } }
Why This Works
Instead of overwriting single variables every time cellForRowAt runs, we’re storing each row’s validation rules and input value in an array. This ensures every text field’s data is preserved and accessible when you need to validate everything at once.
内容的提问来源于stack exchange,提问作者user12381674

