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

Swift中TableView按钮点击无法获取所有cell文本框值的问题解决

Fixing Multi-TextField Validation in UITableView for Swift

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:49:58