How to change background color for tab in tvOS 13?
Asked Answered
S

3

1

enter image description hereTvOS 13. I have a UITabBarController with tabs. And can customize almost everything except this obvious thing: focused tab's background. It's always white. Guide tells

Specify tints for selected and unselected items

I tried:

view.backgroundColor = .purple
tabBar.tintColor = .yellow
tabBar.barTintColor = .red
tabBar.unselectedItemTintColor = .brown
tabBar.backgroundColor = .green
tabBar.backgroundImage = UIColor.blue.toImage()
tabBar.shadowImage = UIColor.orange.toImage()
tabBar.selectionIndicatorImage = UIColor.burgundy.toImage()

Nothing helped.

Scarce answered 10/10, 2019 at 9:59 Comment(3)
I found a workaround (not perfect). I would write it if somebody needs.Scarce
could you please post your solution?Electrophoresis
I found a different way in the end (the intended way), posted it in the answers sectionElectrophoresis
S
2

For @davidv and other folks, here is my solution:

extension UIView {
    func subviews<T:UIView>(ofType type: T.Type) -> [T] {
        var result = self.subviews.compactMap { $0 as? T }
        for sub in self.subviews {
            result.append(contentsOf: sub.subviews(ofType: type))
        }
        return result
    }
}

extension UIViewController {
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        // перекраска кнопки
        let allSubviews = tabBar.subviews(ofType: UIView.self)
        let whiteSubviews = allSubviews.filter { $0.backgroundColor == .white }
        for s in whiteSubviews {
            s.backgroundColor = .gold
        }
    }
}

UPDATE:

For coloring text:

item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorSelected], for: [.focused])
item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorSelected], for: [.highlighted])
item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorUnselected], for: [.normal])

For coloring background:

tabBar.standardAppearance.selectionIndicatorTintColor = .gold
Scarce answered 22/10, 2019 at 7:1 Comment(0)
E
5

After playing a bit with various properties of UITabBar and UITabBarController, I finally figured it out.

The property to change focused items background color is selectionIndicatorTintColor of UITabBarAppearance (documentation).

Since it is available on tvOS >= 13.0, you will have to wrap the assignment like this:

if #available(tvOS 13.0, *) {
    tabBar.standardAppearance.selectionIndicatorTintColor = .white
}
Electrophoresis answered 22/10, 2019 at 8:24 Comment(1)
Thanks but is there a way to change the color of the selected, but unfocused, tabBarItem too? Like the extra dark blue at the top image.Overage
S
2

For @davidv and other folks, here is my solution:

extension UIView {
    func subviews<T:UIView>(ofType type: T.Type) -> [T] {
        var result = self.subviews.compactMap { $0 as? T }
        for sub in self.subviews {
            result.append(contentsOf: sub.subviews(ofType: type))
        }
        return result
    }
}

extension UIViewController {
    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        // перекраска кнопки
        let allSubviews = tabBar.subviews(ofType: UIView.self)
        let whiteSubviews = allSubviews.filter { $0.backgroundColor == .white }
        for s in whiteSubviews {
            s.backgroundColor = .gold
        }
    }
}

UPDATE:

For coloring text:

item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorSelected], for: [.focused])
item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorSelected], for: [.highlighted])
item.setTitleTextAttributes([NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: colorUnselected], for: [.normal])

For coloring background:

tabBar.standardAppearance.selectionIndicatorTintColor = .gold
Scarce answered 22/10, 2019 at 7:1 Comment(0)
E
0

I accomplish this through a UITabBar extension. The view that is displayed on focus contains a UIMotionEffect so we check against that to find it.

@available(tvOS 13.0, *)
extension UITabBar {

    var focusBackgroundView: UIView? {
        let allSubviews: [UIView] = subviews.flatMap { [$0] + $0.subviews as [UIView] }
        return allSubviews.first{ !$0.motionEffects.isEmpty }
    }

}

Usage:

myTabBar.focusBackgroundView.backgroundColor = .red
Economizer answered 6/11, 2019 at 15:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.