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??

Did you set a width constraint for the button ?


That would explain that text is trimmed when bold (because it is larger font).


You could also increase the text label width in IB.

No,


I just set center X and Y constraint. because i thought intrinsic content size will resize the button.

I did test such setting "Bold Text" (under iOS Settings, General, Accessibility).

- if width is constrained, or if there is no centerX constraint, I get the trimming

- but without width constraint and with centerX, the button expands correctly


I tested this with both:

- a basic button

- a button with image defined (selected square arrow up image in background image, gave it a title "Button with long title") and reset the button as system button.

=> is this the type of button with image you mean ?


Same behavior for both. It does not trim text.


XCode 11.2. iOS 13.2. With storyboard, not SwiftUI.

I tested with:

- create a XCode project (XCode 10.3 and XCode 11.2, iOS 11.4 and iOS 13.0) and using storyboard

- add a basic button

- set type custom to the button

- set text color to red

- set text to show!

- set an image to the button

- set constraints center X and Y (didn't set width constraint)


I attached a link which is a screenshot I tested.


http://naver.me/5kKJsfS0


if I didn't set an image to the button, it works.


so I thought it's a bug or I'm missing something.

I repeated your set up with XCode 11.2 beta2.

Except I could not find the IC_Filter image, so I used other, such as link.


No problem at all.

When I change the accessibility setting and return to the app, the button text shows full.


In fact, it works also without centerX.


Where did you get this image from ? I see it is green.

Did you try with another image, just to test (eg, link image).

Could you show the screen of the button constraints ?

my colleague made images. but I think the images have no problem.


and yes, I tried with another images, but the issue is not gone.


if you don't get the issue, I think there's something different your settings or test simulation with me.


so I left a link to check all my asset images and simulation video.

(https://drive.google.com/open?id=1-R6MgNzCfgoUP7_BMOJc4tqKiT3aqgxv)


and thank you for your reply.

Try setting as system button instead of custom.

I tried it. but the issue doesn't solve.


and system button manipulate image color. so I think it doesn't solution. 😟

WHich version of XCode ? Which version of MacOS ?

I'm seeing similar behaviour with segmented controls and buttons. Monitoring the UIAccessibilityBoldTextStatusDidChangeNotification notification and calling invalidateInstrinsicContentSize on the button (or segmented control) in the handler seemed to fix the issue.


But it wasn't always working (e.g. with a segmented control as a custom view in a UIBarButtonItem in a toolbar).

I tested with XCode 10.3, XCode 11.2, MacOS 10.14.6 and XCode 11.2, MacOS 10.15.1


but I thought It doesn't matter OS X and XCode.


the issue is not gone.


I think I should report the issue to apple. it looks a bug.

thanks for your reply.


yeah, that's a problem. if I use a custom view, it doesn't fix..


hmm.. I think there's no way to fix the issue. 😟

Yes file a bug.


But once again, I do not experience the problem unless setting a width constraint.


Of course a not so good work around is to increase button width. But that's just a poor fix.

This seems to be a bug.

The label width inside the button is taken as small as 1.

Try this solution ~!


extension UIButton {

@objc func adjustTitleInsetsForTextImageButton() {

if #available(iOS 13.0, *), ".SFUI-Semibold" == UIFont.systemFont(ofSize: 10).fontName {

titleEdgeInsets = UIEdgeInsets(top: titleEdgeInsets.top, left: titleEdgeInsets.left, bottom: titleEdgeInsets.bottom, right: titleEdgeInsets.right - 1)

}


}

}


And more simple solution


button?.titleLabel?.lineBreakMode = .byClipping

as suggested by @kwangmin

Code Block
button?.titleLabel?.lineBreakMode = .byClipping


worked for me in iOS 13
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 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...

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.

UIButton trimmed text when using bold text
 
 
Q