Rightpoint / BonMot

Beautiful, easy attributed strings in Swift
MIT License
3.56k stars 197 forks source link

UIButton Text Color #279

Closed sealz closed 7 years ago

sealz commented 7 years ago

I am attempting to use BonMot to style the titleLabel's of UIButtons with a custom font and colors.

What I expect to happen When setting the attributedText value for an @IBDesignable UIButton's titleLabel with a string styled by BonMot. It should correctly render in interface builder and it should correctly render when running in the simulator.

What actually happens

The button is rendered correctly in interface builder, but defaults to the system font color for the default button state in the simulator.

The custom button for this example project is:

import Foundation
import UIKit
import BonMot

@IBDesignable class CustomButton: UIButton{

  override public init(frame: CGRect) {
    super.init(frame: frame)
    self.customize()
  }

  required public init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.customize()
  }

  override public func prepareForInterfaceBuilder() {
    self.customize()
  }

  func customize(){

  }
}

@IBDesignable class CallToActionButton: CustomButton{

  override func customize(){
    // MARK: - Colors
    self.backgroundColor = UIColor.black

    //  MARK: - Type
    let style: StringStyle = StringStyle(
      .adapt(.control),
      .font(UIFont(name: "Courier", size: 22.0)!),
      .alignment(.center),
      .color(UIColor.yellow)
    )

    self.titleLabel?.attributedText = titleLabel?.text?.styled(with: style)
  }

}

What I see in interface builder:

screen shot 2017-04-05 at 11 35 26 am

What I see in the simulator:

screen shot 2017-04-05 at 11 37 24 am

Setting the UIButton's type to "Custom" instead of "System" results in the default white text color being used (or whichever text color is selected in interface builder.)

screen shot 2017-04-05 at 11 38 33 am

sealz commented 7 years ago

After typing this up, I realized that I'm taking care of the custom button being displayed in interface builder by calling prepareForInterfaceBuilder in my custom button class, but not accounting for when the button is actually drawn on screen.

This ends up solving the problem, although I am not sure if this is the correct step in the drawing lifecycle in which to add the customizations.

  override public func layoutSubviews() {
    super.layoutSubviews()
    self.customize()
  }

Hope this is helpful for anyone else that runs into the same problem. :)

ZevEisenberg commented 7 years ago

@sealz I'm glad you figured it out! It's kind of weird to call customize() in layoutSubviews(), since I don't think you should have to. Since you're loading from IB, init?(coder:) should be sufficient. But maybe awakeFromNib() is a better place for it? I don't use IB much any more, so I'm a little rusty. Feel free to post back here if you find out anything more. Definitely valuable to have this issue logged in case others have the same problem!