3

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 :

  1. Putting my settitle action around dispatch_async(dispatch_get_main_queue()) {}

  2. Setting title for all differents UIControlStates

  3. Using setAttributedTitle()

  4. Using self.btnParticipate.setNeedsLayout() and self.btnParticipate.layoutIfNeeded() after the setTitle

  5. Disabling the button before and enable it after the setTitle

  6. self.addSubview(self.btnParticipate)

  7. Changing the title in titleLabel.text

  8. Doing everything said previously in the parent viewController using cellActions.btnParticipate

  9. UIView.performWithoutAnimation { self.btnParticipate.setTitle("Annuler", forState: .Normal) }

I’m now stuck and can’t find a solution for that.

Nicolas Meienberger
  • 777
  • 2
  • 8
  • 18

5 Answers5

3

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.

IMike17
  • 81
  • 5
0

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.

  • This solution doesn't work. But I'm not sure if I used it correctly. What I did is when my cell was created, I added the indexPath to an array which was passed to my UITableViewCell and I ran that method just after the setTitle. – Nicolas Meienberger Apr 22 '16 at 13:33
0

Try to wrap your setTitle call into performWithoutAnimation:

UIView.performWithoutAnimation {
    self.btnParticipate.setTitle("Annuler", forState: .Normal)
}
Alexander Doloz
  • 4,078
  • 1
  • 20
  • 36
0

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)
         }
Ahmad Ishfaq
  • 914
  • 1
  • 8
  • 10
0

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.

Nicolas Meienberger
  • 777
  • 2
  • 8
  • 18