UITabBarController Appearance只允许我设置一次



问题是:

我有一个扩展,我已经写了允许在一个标准的UIKit应用程序的标签栏的简单定制。

问题是它工作得很好-一次。

后续更改外观的尝试将被忽略。

如果你能告诉我我做错了什么,我会很感激的。

下面是扩展名。如果我调用setColorsTo(normal:, selected:, disabled: background:),它能正常工作一次;但是再次调用它,没有任何作用。

任何想法?

/* ###################################################################################################################################### */
// MARK: - UITabBarController Extension -
/* ###################################################################################################################################### */
/**
This allows setting the colors for a tab bar.
*/
public extension UITabBarController {
/* ################################################################## */
/**
This allows us to set specific colors for the normal, selected, and background attributes of the tab bar.
All parameters are optional. If not provided, default values for the current theme are used.
- parameters:
- normal: The color to use for an unselected, enabled tab item.
- selected: The color to use for a selected tab item.
- disabled: The color to use for a disabled tab item.
- focused: The color to use for a focused tab item.
- background: The background color to use for the bar.
*/
func setColorsTo(normal inNormalColor: UIColor? = nil,
selected inSelectedColor: UIColor? = nil,
disabled inDisabledColor: UIColor? = nil,
focused inFocusedColor: UIColor? = nil,
background inBackgroundColor: UIColor? = nil) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()

if let backgroundColor = inBackgroundColor {
tabBar.backgroundColor = backgroundColor
tabBar.barTintColor = backgroundColor
appearance.backgroundColor = backgroundColor
}
if let normalColor = inNormalColor {
appearance.stackedLayoutAppearance.normal.iconColor = normalColor
appearance.inlineLayoutAppearance.normal.iconColor = normalColor
appearance.compactInlineLayoutAppearance.normal.iconColor = normalColor
let normalTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: normalColor]
appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
appearance.inlineLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
appearance.compactInlineLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
}

if let selectedColor = inSelectedColor {
appearance.stackedLayoutAppearance.selected.iconColor = selectedColor
appearance.inlineLayoutAppearance.selected.iconColor = selectedColor
appearance.compactInlineLayoutAppearance.selected.iconColor = selectedColor
let selectedTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: selectedColor]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.inlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.compactInlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
}

if let disabledColor = inDisabledColor {
appearance.stackedLayoutAppearance.disabled.iconColor = disabledColor
appearance.compactInlineLayoutAppearance.disabled.iconColor = disabledColor
appearance.inlineLayoutAppearance.disabled.iconColor = disabledColor
let disabledTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: disabledColor]
appearance.stackedLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
appearance.inlineLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
appearance.compactInlineLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
}

if let focusedColor = inFocusedColor {
appearance.stackedLayoutAppearance.focused.iconColor = focusedColor
appearance.inlineLayoutAppearance.focused.iconColor = focusedColor
appearance.compactInlineLayoutAppearance.focused.iconColor = focusedColor
let focusedTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: focusedColor]
appearance.stackedLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
appearance.inlineLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
appearance.compactInlineLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
}
tabBar.standardAppearance = appearance
if #available(iOS 15.0, *) {
tabBar.scrollEdgeAppearance = appearance
}
}
}

无法重现任何问题。你的代码对我来说工作得很好,如果我删除了错误的部分。例如,这里有一个代码的简化,它只设置了选项卡栏的背景颜色,删除了错误的代码行,加上所选选项卡栏项目图标和文本的颜色-以及执行它的视图控制器代码:

extension UITabBarController {
func setColorsTo(selected inSelectedColor: UIColor? = nil,
background inBackgroundColor: UIColor? = nil) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()
if let backgroundColor = inBackgroundColor {
//tabBar.backgroundColor = backgroundColor // wrong
//tabBar.barTintColor = backgroundColor // wrong
appearance.backgroundColor = backgroundColor
}
if let selectedColor = inSelectedColor {
appearance.stackedLayoutAppearance.selected.iconColor = selectedColor
appearance.inlineLayoutAppearance.selected.iconColor = selectedColor
appearance.compactInlineLayoutAppearance.selected.iconColor = selectedColor
let selectedTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: selectedColor]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.inlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.compactInlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
}
tabBar.standardAppearance = appearance
if #available(iOS 15.0, *) {
tabBar.scrollEdgeAppearance = appearance
}
}
}
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
delay(2) {
self.tabBarController?.setColorsTo(selected: .yellow, background: .red)
delay(2) {
self.tabBarController?.setColorsTo(selected: .purple, background: .green)
}
}
}
}

当我运行应用程序时,标签栏变成红色,然后是绿色,而选中的标签栏项目变成黄色,然后是紫色-证明它不止一次工作。因此,我得出结论,如果存在问题,则是由您没有告诉我们的其他代码引起的。

OK。我明白了。

我需要添加一个setNeedsLayout()到标签栏,在设置外观之后:

/* ################################################################## */
/**
This allows us to set specific colors for the normal, selected, disabled, focused, and background attributes of the tab bar.
All parameters are optional. If not provided, default values for the current theme are used.
- parameters:
- normal: The color to use for an unselected, enabled tab item.
- selected: The color to use for a selected tab item.
- disabled: The color to use for a disabled tab item.
- focused: The color to use for a focused tab item.
- background: The background color to use for the bar.
*/
func setColorsTo(normal inNormalColor: UIColor? = nil,
selected inSelectedColor: UIColor? = nil,
disabled inDisabledColor: UIColor? = nil,
focused inFocusedColor: UIColor? = nil,
background inBackgroundColor: UIColor? = nil) {
let appearance = UITabBarAppearance()
appearance.configureWithOpaqueBackground()

if let backgroundColor = inBackgroundColor {
appearance.backgroundColor = backgroundColor
}
if let normalColor = inNormalColor {
appearance.stackedLayoutAppearance.normal.iconColor = normalColor
appearance.inlineLayoutAppearance.normal.iconColor = normalColor
appearance.compactInlineLayoutAppearance.normal.iconColor = normalColor
let normalTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: normalColor]
appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
appearance.inlineLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
appearance.compactInlineLayoutAppearance.normal.titleTextAttributes = normalTextAttributes
}

if let selectedColor = inSelectedColor {
appearance.stackedLayoutAppearance.selected.iconColor = selectedColor
appearance.inlineLayoutAppearance.selected.iconColor = selectedColor
appearance.compactInlineLayoutAppearance.selected.iconColor = selectedColor
let selectedTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: selectedColor]
appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.inlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
appearance.compactInlineLayoutAppearance.selected.titleTextAttributes = selectedTextAttributes
}

if let disabledColor = inDisabledColor {
appearance.stackedLayoutAppearance.disabled.iconColor = disabledColor
appearance.compactInlineLayoutAppearance.disabled.iconColor = disabledColor
appearance.inlineLayoutAppearance.disabled.iconColor = disabledColor
let disabledTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: disabledColor]
appearance.stackedLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
appearance.inlineLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
appearance.compactInlineLayoutAppearance.disabled.titleTextAttributes = disabledTextAttributes
}

if let focusedColor = inFocusedColor {
appearance.stackedLayoutAppearance.focused.iconColor = focusedColor
appearance.inlineLayoutAppearance.focused.iconColor = focusedColor
appearance.compactInlineLayoutAppearance.focused.iconColor = focusedColor
let focusedTextAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: focusedColor]
appearance.stackedLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
appearance.inlineLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
appearance.compactInlineLayoutAppearance.focused.titleTextAttributes = focusedTextAttributes
}
tabBar.standardAppearance = appearance
if #available(iOS 15.0, *) {
tabBar.scrollEdgeAppearance = appearance
}

tabBar.setNeedsLayout()
}

最新更新