sesc360 sesc360 - 4 months ago 29
Swift Question

UIButton does not change title

I want to change the buttons title on clicking the button:

func dispatchStatusButton(title title:String, backgroundColor:UIColor) {
self.btnDispatchStatus.setTitleWithoutAnimation(title.uppercaseString)
self.btnDispatchStatus.backgroundColor = backgroundColor
self.btnDispatchStatus.kern(2.0)
}


When I call the function:

// Set Button
self.dispatchStatusButton(title: "Inaktiv", backgroundColor: UIColor(red: 40.0/255.0, green: 51.0/255.0, blue: 57.0/255.0, alpha: 1.0))


Nothing happens and I have some feeling my kerning function is the reason, but I don't see why:

extension UIButton {
func setTitleWithoutAnimation(title:String?) {
UIView.setAnimationsEnabled(false)
setTitle(title, forState: .Normal)
layoutIfNeeded()
UIView.setAnimationsEnabled(true)
}

func kern(kerningValue:CGFloat) {
let attributedText = NSAttributedString(string: self.titleLabel!.text!, attributes: [NSKernAttributeName:kerningValue, NSFontAttributeName:self.titleLabel!.font, NSForegroundColorAttributeName:self.titleLabel!.textColor])
self.setAttributedTitle(attributedText, forState: UIControlState.Normal)
}
}

Answer

The problem is that self.titleLabel.text property gets updated in the following layout pass. That's why you set the title through setTitle(:forState:) function, and not to the label directly. In your kern function you reference to it when it is still not updated. Try the following:

func kern(kerningValue:CGFloat) {
    let title = self.titleForState(.Normal) ?? "" // This gets the new value
    let attributedText =  NSAttributedString(string: title, attributes: [NSKernAttributeName:kerningValue, NSFontAttributeName:self.titleLabel!.font, NSForegroundColorAttributeName:self.titleLabel!.textColor])
    self.setAttributedTitle(attributedText, forState: UIControlState.Normal)
}