Code Block func addButtons() { for (feed,amount) in feedInventory where amount > 0 { let filteredProducts = feedProducts.filter { $0.code.contains(feed)} for feedProduct in filteredProducts { let horizontalStack = UIStackView() horizontalStack.axis = .horizontal horizontalStack.alignment = .firstBaseline let rationAmount = UILabel(frame: .zero) let rationIndex = Int(rationArrayPosition[feedProduct.code]!) rationAmount.text = "\(myHorses[horseIndex].ration[rationIndex])" horizontalStack.addArrangedSubview(rationAmount) let stepper = UIStepper(frame: .zero) stepper.minimumValue = 0 stepper.maximumValue = 900 stepper.wraps = false stepper.autorepeat = false stepper.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged) stepper.accessibilityLabel = "\(feedProduct.code)" horizontalStack.addArrangedSubview(stepper) feedStack.addArrangedSubview(horizontalStack) }}} func removeButtons() { let rows = feedStack.arrangedSubviews .filter {$0 is UIStackView} for row in rows { feedStack.removeArrangedSubview(row) row.removeFromSuperview() }} @objc func stepperValueChanged(_ sender:UIStepper!) { let rationIndex = rationArrayPosition[sender.accessibilityLabel!] //This is where I have trouble* myHorses[horseIndex].ration[rationIndex ?? 00] += Int(sender.value) removeButtons() addButtons() }
I can't use = Int(sender.value) because this resets to 0 each time I press the button, but how can I update the values without using removeButtons() and addButtons()?
Thanks. If you created a new project and copied the code in your opening post, you would have found what were missing more easily.struct FeedProduct {
I guess you cannot use = Int(sender.value) because you are not setting the value property of the stepper.I can't use = Int(sender.value) because this resets to 0 each time I press the button,
You just need to update the text property of the corresponding UILabel in the action method stepperValueChanged.how can I update the values without using removeButtons() and addButtons()?
To achieve this, you need to access the right UILabel in that method.
To make things easier, you can encapsulate each row into a class:
LabelStepper.swift
Code Block import UIKit class LabelStepper: UIStackView { typealias ActionHandler = (LabelStepper)->Void /// A handler called on `.valueChanged` of `stepper` var onValueChanged: ActionHandler? let label: UILabel let rationAmount: UILabel //<- The right UILabel let stepper: UIStepper init(text: String, value: Int, onValueChanged: ActionHandler?) { let label = UILabel(frame: .zero) let rationAmount = UILabel(frame: .zero) let stepper = UIStepper(frame: .zero) self.label = label self.rationAmount = rationAmount self.stepper = stepper self.onValueChanged = onValueChanged super.init(frame: .zero) let horizontalStack = self horizontalStack.axis = .horizontal horizontalStack.alignment = .firstBaseline //<- You can try other values... //horizontalStack.distribution = .fillEqually label.text = text horizontalStack.addArrangedSubview(label) rationAmount.text = "\(value)" horizontalStack.addArrangedSubview(rationAmount) stepper.value = Double(value) //<- Please do not forget to set `value` stepper.minimumValue = 0 stepper.maximumValue = 900 stepper.wraps = false stepper.autorepeat = false stepper.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged) horizontalStack.addArrangedSubview(stepper) } required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc func stepperValueChanged(_ sender: UIStepper) { rationAmount.text = "\(Int(sender.value))" //<- Update the `text` property of the right UILabel onValueChanged?(self) } }
And use it in the VC:
Code Block func addButtons() { for (feed,amount) in feedInventory where amount > 0 { let filteredProducts = feedProducts.filter { $0.code.contains(feed)} for feedProduct in filteredProducts { let rationIndex = rationArrayPosition[feedProduct.code]! let value = myHorses[horseIndex].ration[rationIndex] let horizontalStack = LabelStepper( text: "\(feedProduct.name)", value: value ) {labelStepper in myHorses[horseIndex].ration[rationIndex] = Int(labelStepper.stepper.value) } horizontalStack.stepper.accessibilityLabel = "\(feedProduct.code)" feedStack.addArrangedSubview(horizontalStack) } } }