Reputation: 992
I have stepper in my UITableViewCells. I saw from other answers that people are using UIStepper.tag to pass the indexPath.row , but I have sections in my UITableView and I need to save the indexPath directly in the class UIStepper.
extension UIStepper {
struct Save {
static var indexPath:IndexPath?
}
public var indexPath:IndexPath {
get{
return Save.indexPath!
}
set(newValue) {
Save.indexPath = newValue
}
}
}
I'm using this code to store the indexPath. In my cellForRow
I set
stepper.indexPath = indexPath
, but my indexPath for the UIStepper is always the last one.
Every UIStepper have the last indexPath.
If I have 4 rows, the output UIStepper.indexPath.row is always 3 for all cells.
How to fix that?
Upvotes: 3
Views: 93
Reputation: 258057
What you try to do in extension UIStepper
is bad.
Disclaimer: What I propose below is also bad, even worse. If you can, avoid this approach and use inheritance as proposed by @George_Alegre - this is the best and correct way.
But... if for some very very strange reason you cannot use subclassing it is possible to make what you did operable. The main issue is in static
- it is shared between all instances of a class, that is why all your steppers have the latest set value. So, let's just replace one value with container which will hold pairs of reference to instance and desired value.
IMPORTANT: YOU MUST CLEAN THAT CONTAINER AFTER WORK WITH THIS WORKFLOW eg. in deinit of controller that manages this table
Here is approach:
extension UIStepper {
struct Save {
static var indexPaths = [UIStepper: IndexPath]()
// !!! MUST BE CALLED AT THE END OF USAGE (eg. in controller deinit)
static func cleanup() {
indexPaths = [:]
}
}
public var indexPath: IndexPath {
get {
return Save.indexPaths[self] ?? IndexPath()
}
set(newValue) {
Save.indexPaths[self] = newValue
}
}
}
Upvotes: 0
Reputation: 166
I understand what you're trying to do. I don't know if it's the best solution but the problem you're having is caused because the property is static for the whole class, so when you set the value for whatever row, what you had before gets overwritten.
When you load the first cell with cellForRowAt
, you set the indexPath to 0-0. For the second row, you set it to 0-1, and so on. The last row sets it to whatever value it has at that moment and whatever you had before gets lost.
In other words, that value is shared for all instances (it's a class property).
What you need is an instance property so each object has its own memory for that value. Instead of using an extension, you could create a UIStepper subclass that only adds an indexPath
property to its definition and use that instead. Something like:
class CellStepper: UIStepper {
var indexPath: IndexPath?
}
Then, in cellForRowAt
set it to the value you need.
I suppose you're setting the same method as target for valueChanged
to each stepper and when that gets called, you could use the sender to cast it to CellStepper
and access the indexPath property to know what row's stepper changed.
If you'd like sample code, I can elaborate.
Upvotes: 2