Reputation: 777
I’m reopening this question because my last one wast flagged as duplicate even if it’s actually not ! It’s the same problem but the solutions are not working with my code. I’m using swift 2.
So my problem is, as the title says : I have a UIButton in a tableViewCell and when I use the method « setTitle », it takes from 10 to 60 seconds to update the title. At the same time I’m using « addTarget » and it works instantly. So the title should also update. My button is set as « custom » in my storyboard.
When the view is loading I’m running the following code :
/* viewDidLoad */
override func viewDidLoad() {
super.viewDidLoad()
boolAlready = false
findParticipation()
}
/* findParticipation */
func findParticipation() {
// After server request response :
boolAlready = true
self.tableView.reloadData()
}
/* cellForRowAtIndexPath */
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellActions = tableView.dequeueReusableCellWithIdentifier(informationsCellArray[indexPath.row], forIndexPath: indexPath) as ! eventDetailsAction
if boolAlready {
cellActions.foundParticipation
} else {
cellActions.btnParticipate.setTitle("...", forState: UIControlState.Normal)
cellActions.btnParticipate.addTarget(self, action: « deleteParticion", forControlEvents: .TouchUpInside)
}
/* In my custom cell */
func foundParticipation () {
self.btnParticipate.setTitle("Annuler", forState: UIControlState.Normal)
self.btnParticipate.addTarget(self, action: "deleteParticipation", forControlEvents: .TouchUpInside)
}
Different things I found on forums that didn’t worked :
Putting my settitle action around
dispatch_async(dispatch_get_main_queue()) {}
Setting title for all differents UIControlStates
Using setAttributedTitle()
Using self.btnParticipate.setNeedsLayout()
and self.btnParticipate.layoutIfNeeded()
after the setTitle
Disabling the button before and enable it after the setTitle
self.addSubview(self.btnParticipate)
Changing the title in titleLabel.text
Doing everything said previously in the parent viewController using cellActions.btnParticipate
UIView.performWithoutAnimation {
self.btnParticipate.setTitle("Annuler", forState: .Normal)
}
I’m now stuck and can’t find a solution for that.
Upvotes: 3
Views: 1060
Reputation: 81
You can try to refer to this answer https://stackoverflow.com/a/29633647/4478037
Make sure your button is a "custom" button and not a "system" button.
Upvotes: 3
Reputation: 777
So after 1 week of tries, I decided to stop searching... I'm just calling findParticipation() synchronously and I'm not instantiating my tableView until I get foundParticipation() response.
I know it's way worse for the UX but it's still less time to wait.
Upvotes: 0
Reputation:
You can use
reloadRowsAtIndexPaths(_:withRowAnimation:)
to force a reload of the cell.
When the title changes that means that your code seems to be correct and its about rendering cycles. This would be one way to to reload the cell.
For reference: Apple Docs - UITableView reloadRowsAtIndexPaths
EDIT:
You have to call this method when some event gets fired, an requests finished etc. to update the cell. I had a second look at your code and it seems that your if-else in cell for row at index path is not doing what it should do. You should NOT call there any "action-performing-methods". Its just for initialization.
Your problem seems to be that your boolean boolAlready is the same for all cells. That will result in a never executing else-block. An therefore the title is not set, or its just set when the bool is set to false. You should probably print the bool there. And/or update your post with more information.
And its not good-readable code when you use nearly identical names like findParticipation and foundParticipation. You should probably refactor that.
Upvotes: 0
Reputation: 914
Your issue is when you are creating the cell the btnParticipate function won't run properly you have to code all those conditions in func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) method
Try this
let cellActions = tableView.dequeueReusableCellWithIdentifier(informationsCellArray[indexPath.row], forIndexPath: indexPath) as ! eventDetailsAction
cellActions.removeTarget(nil, action: nil, forControlEvents: .AllEvents)
if boolAlready {
cellActions.btnParticipate.setTitle("Annuler", forState: UIControlState.Normal)
cellActions.btnParticipate.addTarget(self, action: "deleteParticipation", forControlEvents: .TouchUpInside)
} else {
cellActions.btnParticipate.setTitle("...", forState: UIControlState.Normal)
cellActions.btnParticipate.addTarget(self, action: « deleteParticion", forControlEvents: .TouchUpInside)
}
Upvotes: 0
Reputation: 4188
Try to wrap your setTitle
call into performWithoutAnimation
:
UIView.performWithoutAnimation {
self.btnParticipate.setTitle("Annuler", forState: .Normal)
}
Upvotes: 0