Is there a way to set something like adjustsfontsizetofitwidth on UITabBarItem

998 Views Asked by At

Trying to get my app accessible for all users and I stumbled upon an issue when creating the items for the TabBar and would love to have a way of fixing it.

I got something like this in my project:

func setupTabBarItems(tabName: String, tabImage: UIImage?, tabSelectedImage: UIImage?) {
    let tabBarItem = UITabBarItem(title: tabName, image: tabImage, selectedImage: tabSelectedImage)

    tabBarItem.title = tabName
    tabBarItem.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: AppColor.primary], for: .selected)
    tabBarItem.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: AppColor.darkDeep], for: .normal)
    tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: AppFont.medium(12)], for: .normal)

    tabBarItem.imageInsets = UIEdgeInsets.init(top: -10, left: 0, bottom: 0, right: 0)
    tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -18)

    DispatchQueue.main.async {
        self.navigationController.tabBarItem = tabBarItem
    }
}

and:

static func medium(_ fontSize: CGFloat) -> UIFont {
    let font = UIFont(name: AppFont.someRandomTextFont, size: fontSize)!
    let fontMetrics = UIFontMetrics(forTextStyle: .body)
    return fontMetrics.scaledFont(for: font)
}

When increasing the dynamic text type, the title gets out of the actual item. For example, when doing this for a UILabel I just check the "Automatically Adjust Font" option and update "Minimum Font Scale" to 0.25.

Is there any way to do something like this in the code describing the TabBarItem programmatically?

Thank you so much!

4

There are 4 best solutions below

1
On

Late answer, I know. But I just stumbled over Large Content Viewer, introduced in iOS 13.

If user has set the device's font (or the app-specific font) to something in the accessibility font range, you get Large Content Viewer for free. Tap and hold the tab bar item to see a large view of the tab bar item, with enlarged image and text.

https://a11y-guidelines.orange.com/en/mobile/ios/wwdc/2019/261/ has a nice summary. The original WWDC video was WWDC 2019, session 261. Note that you'll want the image asset to be a vector format if possible.

There's also a protocol, UILargeContentViewerItem, that your custom API can adopt.

This seems to be Apple's preferred way of making tab bar items, status bars, nav bars, standard UIKit controls, and images accessible to low-vision users who aren't using an assistive device.

0
On

UITabBarItem doesn't contain label - so that you will be able to set minimum scale directly.

Suggestion would be to go with custom views instead of UITabBarItems.

Or if you prefer to continue with UITabBarItem, I suggest that you do measuring by yourself. Measure the size of the text/font you want and if it's too big, make the font size small enough that it will fit.

0
On

You can get it something like this

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    tabBar.subviews.forEach { barButton in
        barButton.subviews.forEach { subview in
            if let label = subview as? UILabel {
                label.adjustsFontSizeToFitWidth = true
            }
        }
    }
}
0
On

Is there any way to do something like this in the code describing the TabBarItem programmatically?

No, the UITabBarItem is definitely not made for this kind of purpose.
You can change some attributes using the appearance proxy for instance but there's no such things provided by Apple to handle your situation.

Trying to get my app accessible for all users...

I understand you're willing to implement a11y and Apple introduced an interesting feature dealing with UITabBarItem: the Large Content Viewer.
The UITabBarItem inherits from UIBarItem that exposes some largeContent... properties which highlights this feature I do recommend.

I'm not sure your concept may provide more a11y to your app because the tab bar items aren't made for that in my view.
Anyway, I always try to avoid text in my tab bars: explicit SF Symbols may be another appropriate solution.

IF you really want to follow your idea, you could be informed of the text sizes setting (traitCollectionDidChange) and adapt your font size accordingly using the 'mmmatey' method for instance (measurements ) ⟹ why not but I really don't recommend this way of conception.