在 UIBarButtonItem 上调用 setTitleTextAttributes 对 iOS 11 没有任何影响

Posted

技术标签:

【中文标题】在 UIBarButtonItem 上调用 setTitleTextAttributes 对 iOS 11 没有任何影响【英文标题】:Calling setTitleTextAttributes on UIBarButtonItem does not have any impact on iOS 11 【发布时间】:2018-10-12 10:41:17 【问题描述】:

我在didFinishLaunchingWithOptions 中使用外观代理在整个项目中设置UIBarButtonItem 标题字体,如下所示:

UIBarButtonItem.appearance().setTitleTextAttributes([
                NSAttributedStringKey.font: customFont
            ]
            , for: .normal)

我想做的是根据用户选择更改此字体? 因此,当用户选择一种字体时,我将其存储在 UserDefaults 中,并向我知道有 UIBarButtonItems 的那些视图控制器发送本地通知,然后我像这样直接重置每个:

navigationItem.leftBarButtonItems?.forEach  $0.setTitleTextAttributes([NSAttributedStringKey.font: ...], for: .normal) 
navigationItem.rightBarButtonItems?.forEach  $0.setTitleTextAttributes([NSAttributedStringKey.font: ...], for: .normal) 
navigationItem.backBarButtonItem?.setTitleTextAttributes([NSAttributedStringKey.font: customFont], for: .normal)

这在 ios 10 中按预期工作,但在 iOS 11 中,它不会对左、右或后退栏按钮项目立即产生影响。

如果视图控制器被弹出然后再次推送到导航堆栈,则后退栏按钮项目将调整为新字体 - 栏按钮项目在下一次应用运行之前不会更改。

我很自然地在 AppDelegate 中对导航栏标题做同样的事情:

UINavigationBar.appearance().titleTextAttributes = [
        NSAttributedStringKey.font: ...
    ]
    if #available(iOS 11.0, *) 
        UINavigationBar.appearance().largeTitleTextAttributes = [
            NSAttributedStringKey.font : ...
        ]
    

在每个视图控制器中,我再次重置这些值,并且标题会立即更改字体。

我尝试在每个控件状态下将栏按钮项的标题文本属性设置为新字体,即:[.normal, .highlighted, .disabled],没有运气。

我还尝试将navigationItem.leftBarButtonItem 设置为UIBarButonItem 的新实例,希望这将具有新字体,但按钮完全消失:D

我尝试的最后一件事是在导航栏上调用setNeedsDisplaylayoutIfNeeded,但仍然没有任何反应。

该案例的示例项目可以找到here

【问题讨论】:

试试this,对我来说效果很好 【参考方案1】:

这里有一个超级 hacky 的机制来解决看似明显的错误(或未记录的优化):

    for controlState in [UIControlState.disabled, .highlighted, .normal] 

        self.changeBarButtonFont(barButtonItem: self.updateButton, font: font, controlState: controlState)

        self.changeBarButtonFont(barButtonItem: self.selectButton, font: font, controlState: controlState)
    


private func changeBarButtonFont(barButtonItem: UIBarButtonItem, font: UIFont, controlState: UIControlState) 
    barButtonItem.title = barButtonItem.title! + " "

    barButtonItem.setTitleTextAttributes([NSAttributedStringKey.font : font], for: controlState)

    DispatchQueue.main.async
    
        barButtonItem.title = barButtonItem.title?.trimmingCharacters(in: CharacterSet.whitespaces)
    

请注意,这不会 100% 有效,因为快速点击“更改字体”不会注册。但也许你可以解决这个问题?

【讨论】:

以上是关于在 UIBarButtonItem 上调用 setTitleTextAttributes 对 iOS 11 没有任何影响的主要内容,如果未能解决你的问题,请参考以下文章

无法将 Action 设置为在情节提要上创建的 UIBarButtonItem

UIBarButtonItem 仅在我滑动时被调用

UIToolBar 上的 UIBarbuttonItem 的动作没有被调用

没有为 UIBarButtonItem 调用 iOS 选择器

UIBarbuttonItem 没有调用动作方法

以编程方式添加到导航栏的UIBarButtonItem无法调用选择器,而添加到工具栏的按钮确实如此