Reputation: 177
I am fairly new at coding in swift and I've been trying to find a solution to my problem for the past couple days, and am not able to.
I have a class named userData
with various properties:
class UserData {
var name: String
var age: Int
var credits: Int = 1
...
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
Inside the viewController.swift I have declared an object of this class:
...
var user = UserData(name: "testing", age: 5)
...
Inside the same viewController
I have a UITableView
with a few UITableViewCells
. In every cell there is a UIStepper
Using the UIStepper
from a cell I want to increment or decrement the property credits
of my object user
that sits inside the viewController.swift, and do that from within the tableViewCell.swift file
From what I can find, I think I should use a delegate but I can figure out how to implement it.
More information: Pardon the art work, I am not an artist...
The user has a set amount of ants available to work (this number is a property of my object user). There is also a property for the amount of ants currently working ('ants used' in my screen shot).
At first, the white label on top says '0/5' (Meaning the user has 5 available ants to work but none are currently working).
When the user increments the stepper for 'scavenger ants', the white label on top should say '1/5' (Meaning that there is currently 1 ant working out of 5 that are available).
What I want to do, is that when the user clicks on a stepper, the user's property for the 'ants currently working' increments or decrements appropriately.
Thank you
Upvotes: 1
Views: 95
Reputation: 864
Set that logic up in the view controllers' cellForRowAt
.
When setting up the cell, you can add a function inside your view controller as the target every-time the UIStepper value changes:
// inside cellForRowAtIndexPath:
cell.addTarget(self, action: #selector(doSomething(sender:), for: .valueChanged)
Inside doSomething
you set up the logic for updating your model.
func doSomething(sender: UIStepper) {
// do stuff here
}
Edit with an example of the delegate pattern which would be a better solution, for future readers.
First create a protocol:
protocol StepperCellDelegate {
func didChangeValueForStepper(inCell: Cell, whateverInfoYouWantHere:...)
func otherUsefulFunctions(...)
}
In your cell class, set a target/action for when your value is changed:
// inside the cell's initialization (`init(style:reuseIdentifier:)`
self.addTarget(self, action: #selector(valueChanged(sender:), for: .valueChanged)
Your cell also needs a delegate property:
weak var stepperCellDelegate: StepperCellDelegate?
doSomething
would look something like this:
func valueChanged(sender: UIStepper) {
stepperCellDelegate?.didChangeValueForStepper(inCell: self, ...)
}
Your ViewController will implement the protocol
extension MyViewController: StepperCellDelegate {
func didChangeValueForStepper(inCell: Cell, whateverInfoYouWantHere:...) {
// implementation here
}
func otherUsefulFunctions(...){
// implementation here
}
}
And inside cellForRowAtIndexPath
set itself as the delegate:
// inside cellForRowAtIndexPath:
cell.stepperCellDelegate = self
Upvotes: 2
Reputation: 326
Delegation is the proper way of handling this.
That UItableviewCell — both appear to be similar — should expose a protocol with a set of methods that the UIViewController can implement. Methods are triggered when you tap on the UIStepper widget.
Best to stick to this methodology, and reuse it everywhere. Makes things manageable loosely coupled.
Upvotes: 1