UIButton trimmed text when using bold text

i made an UIButton with image and text using storyboard. which has center X and Y constraints in UIViewController.view

(that's all. my UIViewController just has one UIButton.)


then run my app, it looks fine.


but When setting "Bold Text" (under iOS Settings, General, Accessibility), my button trimmed text.


i didn't use any custom font. just set an image size 20*20 and text (e.g hello)


is this known issue or am i missing something??

Post not yet marked as solved Up vote post of mschoiloen Down vote post of mschoiloen
11k views
  • I can't remember how long I've had this issue! I just realized today that it was due to my Bold Text setting being turned on. I thought it was issues with a few of the apps I use. Hopefully it'll be fixed eventually

  • one year later, iOS 16 is out and it is still happening...

Add a Comment

Replies

I was able to reproduce this on iOS 13 and on iOS 14 (beta 3) - Filed another feedback (8115220) for this.

I dug a bit further into this and it seems that UIButton isn't reporting the correct intrinsicContentSize when bold text is enabled.

From a small experiment I subclassed UIButton to print out the intrinsicContentSize of the button itself and some of its subviews:

Code Block swift
private class Button: UIButton {
        override var intrinsicContentSize: CGSize {
            let size = super.intrinsicContentSize
            guard let imageView = imageView, let titleLabel = titleLabel else {
                return size
            }
            print("""
            button.intrinsicContentSize = \(size)
                button.titleLabel.intrinsicContentSize = \(titleLabel.intrinsicContentSize)
                button.titleLabel.sizeThatFits = \(titleLabel.sizeThatFits(CGSize(width: .max, height: .max)))
                button.imageView.intrinsicContentSize = \(imageView.intrinsicContentSize)
                button.imageView.sizeThatFits = \(imageView.sizeThatFits(CGSize(width: .max, height: .max)))
            """)
return size
        }
    }


For a simple use case:

Code Block swift
    func makeButton() -> UIButton {
        let button = Button(type: .system)
        let image = UIImage(named: "menu")
        button.setImage(image, for: .normal)
        button.setTitle("Menu", for: .normal)
        return button
    }


We get the following results

for Normal Text:

Code Block
intrinsicContentSize = (68.0, 29.0)
button.titleLabel..intrinsicContentSize = (38.5, 18.0)
button.titleLabel..sizeThatFits = (38.5, 18.0)
button.imageView.intrinsicContentSize = (29.0, 29.0)
button.imageView.sizeThatFits = (29.0, 29.0)


when Bold Text is enabled:

Code Block
button.intrinsicContentSize = (69.0, 29.0)
button.titleLabel.intrinsicContentSize = (40.0, 18.0)
button.titleLabel.sizeThatFits = (40.0, 18.0)
button.imageView.intrinsicContentSize = (29.0, 29.0)
button.imageView.sizeThatFits = (30.0, 30.0)


Notice the button's imageView isn't reporting the correct intrinsicContentSize when bold text is enabled, interestingly it does report the correct size when asking for sizeThatFits!!

A workaround I found is to manually add the size diff to the intrinsic content size of the button, but that isn't fool proof as there could be situations / configurations where that isn't correct.

e.g.

Code Block swift
        override var intrinsicContentSize: CGSize {
            let size = super.intrinsicContentSize
            guard let imageView = imageView else {
                return size
            }
let imageSizeThatFits = imageView.sizeThatFits(CGSize(width: .max, height: .max))
            let imageIntrinsicSize = imageView.intrinsicContentSize
            let sizeDiff = CGSize(width: imageSizeThatFits.width - imageIntrinsicSize.width,
                                  height: imageSizeThatFits.height - imageIntrinsicSize.height)
            return CGSize(width: size.width + sizeDiff.width,
                          height: size.height + sizeDiff.height)
}

I've just noticed this issue myself on iOS 17, and have found that it seems to only truncate the button title when the image uses the template rendering mode.

// The following causes the title to be truncated when bold text is turned on,
// because the image width increases slightly
setImage(myImage.withRenderingMode(.alwaysTemplate), for: .normal)

// The following prevents the image size from changing when bold text is enabled
setImage(myImage.withRenderingMode(.alwaysOriginal), for: .normal) 

Seems like an unusual bug with UIButton, but at least this fix/workaround is simpler than attempting to calculate changes to the intrinsic content size.