swiftuitableviewuibuttonpaddinguiedgeinsets

Swift: UIButton edgeinsets applies after cell redrawn/scroll


After couple of days struggling I wanted to ask you about UIButton title and image edge insets...

I have custom cell with button and on that button depends on cell type should be different icons and text but the requirement text should be centered and image could be left aligned or right. For that I'm setting edge insets during updating button tile and image. To keep it simple I hard coded image insets left to be 8 and the calculating left point of title from which text should start.

func setTitleWithImage(_ title: String, imageName: String) {
    self.btnStatus.setTitle(title, for: .normal)
    self.btnStatus.setImage(UIImage(named: imageName), for: .normal)
    
    self.btnStatus.imageEdgeInsets.left = 8
    let btnWidth = btnStatus.frame.width
    let titleLabelWidth = btnStatus.titleLabel?.frame.width
    self.btnStatus.titleEdgeInsets.left = (btnWidth / 2) - (titleLabelWidth! / 2) - (btnStatus.imageView?.frame.width)! + self.btnStatus.imageEdgeInsets.left
}

The problem is that when tableview loaded it is wrong aligned but after scrolling/redraw cell it is aligned correctly. I tried different suggestions but no one helped me.

Before scroll

Before Scroll

After scroll

After scroll

To be more specific here is the whole project:

Sources

UPDATED

ViewController almost all for more detailed please download source

   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 140
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
    cell.setTitleWithImage("DIFFERENT TEXT IS HERE ?", imageName: "icon")
    cell.layoutIfNeeded()
    cell.setNeedsLayout()
    
    
    return cell
}

Solution

  • func alignTitleWithImageFrames () {
        let btnWidth = btnStatus.frame.width
        let titleLabelWidth = btnStatus.titleLabel?.frame.width
        self.btnStatus.titleEdgeInsets.left = (btnWidth / 2) - (titleLabelWidth! / 2) - (btnStatus.imageView?.frame.width)! + 13
        self.btnStatus.imageEdgeInsets.left = 8
    }