Swift3中如何按追加值的方式实现数值累加?
Hey there! Let’s walk through how to implement the quantity accumulation via append values for your existing Swift3 shopping cart code. I’ll break this down by modifying each component you mentioned—models, cells, view model, and view controller—so it fits seamlessly with your current setup.
1. Update QM_CartModel to Support Accumulation
First, we need to add a method to your data model that handles quantity increments/decrements (instead of overwriting the value directly). This keeps business logic encapsulated where it belongs:
class QM_CartModel: NSObject { // Your existing properties (example): var goodsId: String? var goodsName: String? var count: Int = 0 // Current quantity of the item // New method to handle append/accumulation func appendCount(with delta: Int) { // Ensure quantity never drops below 0 (adjust this rule if you allow negative stock for pre-orders) count = max(0, count + delta) } }
The delta parameter is the value you want to add (positive) or subtract (negative). The max(0, ...) ensures we don’t end up with invalid negative quantities.
2. Modify QM_ChartViewModel to Handle Business Logic
Your view model acts as the middle layer between view and data. We’ll add a method to trigger accumulation, plus a way to notify the view to refresh:
class QM_ChartViewModel: NSObject { // Your existing data source: var dataSource: [QM_ChartDataSourceModel] = [] // Closure to notify the view controller to update UI var onDataUpdated: (() -> Void)? // New method to update quantity at a specific index func appendQuantity(at index: Int, delta: Int) { guard index >= 0 && index < dataSource.count else { return } // Access the underlying QM_CartModel from your data source model let sourceModel = dataSource[index] sourceModel.cartModel?.appendCount(with: delta) // Trigger UI update onDataUpdated?() } }
Assuming QM_ChartDataSourceModel holds a reference to QM_CartModel (named cartModel here—adjust the property name if yours is different).
3. Update QM_CartCell to Capture User Input
Your table cell needs a way for users to input the append value (like a text field + button, or custom stepper). Here’s how to wire it up without letting the cell modify data directly:
class QM_CartCell: UITableViewCell { // Your existing UI elements: @IBOutlet weak var goodsNameLabel: UILabel! @IBOutlet weak var currentCountLabel: UILabel! @IBOutlet weak var appendValueTextField: UITextField! // Input for append value // Closure to pass the append request up to the view controller var onAppendTapped: ((Int) -> Void)? // Configure cell with data func setup(with model: QM_ChartDataSourceModel) { goodsNameLabel.text = model.cartModel?.goodsName currentCountLabel.text = "\(model.cartModel?.count ?? 0)" } // Action for your "Append" button @IBAction func appendButtonPressed(_ sender: UIButton) { guard let inputText = appendValueTextField.text, let delta = Int(inputText) else { // Show alert or hint for invalid input return } // Pass the delta value up to the view controller onAppendTapped?(delta) // Clear the input field after submission appendValueTextField.text = "" } }
The cell only captures user input and delegates data modification to the view controller—this follows the single responsibility principle.
4. Wire It All Up in the View Controller
Finally, connect the cell, view model, and table view in your view controller to make the flow work:
class CartViewController: UIViewController { @IBOutlet weak var cartTableView: UITableView! private let cartViewModel = QM_ChartViewModel() override func viewDidLoad() { super.viewDidLoad() setupTableView() setupViewModelBinding() // Load your initial cart data here... } private func setupTableView() { cartTableView.register(UINib(nibName: "QM_CartCell", bundle: nil), forCellReuseIdentifier: "QM_CartCell") cartTableView.dataSource = self cartTableView.delegate = self } private func setupViewModelBinding() { // Refresh table when data updates, ensure UI work runs on main thread cartViewModel.onDataUpdated = { [weak self] in DispatchQueue.main.async { self?.cartTableView.reloadData() } } } } // MARK: - UITableView DataSource & Delegate extension CartViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return cartViewModel.dataSource.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "QM_CartCell", for: indexPath) as! QM_CartCell let model = cartViewModel.dataSource[indexPath.row] cell.setup(with: model) // Bind the cell's append action to the view model cell.onAppendTapped = { [weak self] delta in self?.cartViewModel.appendQuantity(at: indexPath.row, delta: delta) } return cell } }
Key Notes to Keep in Mind
- Input Validation: You can enhance the cell’s input check to handle decimal values (if needed) or restrict to positive/negative numbers based on your business rules.
- Thread Safety: The
onDataUpdatedclosure usesDispatchQueue.main.asyncto ensure UI updates happen on the main thread—critical for avoiding crashes. - Customization: Adjust the
appendCountmethod inQM_CartModelif you need additional rules (like limiting maximum quantity per item).
内容的提问来源于stack exchange,提问作者abel

