SwiftUI NavigationBar 后退按钮在使用自定义字体时抱怨图标缩放

Posted

技术标签:

【中文标题】SwiftUI NavigationBar 后退按钮在使用自定义字体时抱怨图标缩放【英文标题】:SwiftUI NavigationBar back button complains about icon scaling when using custom font 【发布时间】:2021-10-14 12:37:22 【问题描述】:

我在运行我的应用程序时看到大量日志,告诉我后退按钮图标 (chevron.backward) 正在缩放。

2021-10-14 13:54:32.306371+0200 MyApp[37123:18219419] [framework] CoreUI: -[CUICatalog namedVectorGlyphWithName:scaleFactor:deviceIdiom:layoutDirection:glyphSize:glyphWeight:glyphpointSize:appearanceName:] 'chevron.backward' called with scaleFactor == 2.000000 glyphPointSize == 0.000000 at '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/ios.simruntime/Contents/Resources/RuntimeRoot/System/Library/CoreServices/CoreGlyphs.bundle/Assets.car'
2021-10-14 13:54:32.386602+0200 MyApp[37123:18219419] [framework] CoreUI: -[CUICatalog namedVectorGlyphWithName:scaleFactor:deviceIdiom:layoutDirection:glyphSize:glyphWeight:glyphPointSize:appearanceName:] 'UINavigationBarTitleTransitionBackIndicatorMaskSymbol' called with scaleFactor == 2.000000 glyphPointSize == 0.000000 at '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/UIKitCore.framework/Artwork.bundle/Assets.car'

我的应用程序中的所有后退按钮都是由操作系统创建的,即我不会手动将后退按钮添加到 NavigationBar。但是,我确实通过设置要通过ViewModifier 使用的字体和前景色来为NavigationBar 设置主题。不应用视图修饰符会使所有日志静音,所以我猜我使用自定义字体会导致这些消息。该应用程序面向 iOS 15 及更高版本,我正在 XCode 13 上进行编码。

我在我的App 中调用过一次视图修改器:

struct MyApp:App 
  var body: some Scene 
    WindowGroup 
      NavigationView 
        ContentView
      
      .navigationBarThemed()
    
  

ViewModifier

// MARK: Navigation Bar
extension View 
  public func navigationBarThemed() -> some View 
    self.modifier(ThemedNavigationBar())
  


private struct ThemedNavigationBar:ViewModifier 
  // MARK: Back button
  var backButtonAppearance: UIBarButtonItemAppearance 
    let backButtonAppearance = UIBarButtonItemAppearance()
    backButtonAppearance.normal.titleTextAttributes = [
      NSAttributedString.Key.font: UIFont(name: Font.myFont.weights.regular, size: Font.sizes.navigationBarButton)!,
      NSAttributedString.Key.foregroundColor: UIColor(Color.highlight)
    ]
    backButtonAppearance.focused.titleTextAttributes = [
      NSAttributedString.Key.font: UIFont(name: Font.myFont.weights.regular, size: Font.sizes.navigationBarButton)!,
      NSAttributedString.Key.foregroundColor: UIColor(Color.highlight)
    ]
    
    return backButtonAppearance
  
  
  // MARK: Large Title
  var largeTitleTextAttributes:[NSAttributedString.Key : Any] = [
    NSAttributedString.Key.font: UIFont(name: Font.myFont.weights.regular, size: Font.sizes.navigationBarLargeTitle)!,
    NSAttributedString.Key.foregroundColor: UIColor(Color.text)
  ]
  
  var theme:UINavigationBarAppearance 
    let themedAppearance = UINavigationBarAppearance()
    themedAppearance.configureWithTransparentBackground()
    themedAppearance.backgroundColor = UIColor(Color.background)
    themedAppearance.backButtonAppearance = self.backButtonAppearance
    themedAppearance.largeTitleTextAttributes = self.largeTitleTextAttributes
    
    return themedAppearance
  
  
  init() 
    UINavigationBar.appearance().standardAppearance = self.theme
    UINavigationBar.appearance().scrollEdgeAppearance = self.theme
    UINavigationBar.appearance().compactAppearance = self.theme
  
  
  public func body(content: Content) -> some View 
    content
  

如何在 NavigationBar 中使用自定义字体而不导致这些缩放日志?

【问题讨论】:

【参考方案1】:

不是一个真正的答案,但可能对任何最终来到这里的人有所帮助:

我无法解决上述主题ViewModifier 的问题。相反,我创建了一个 BackButton 视图和一个随附的 .navigationBarBackButton() 视图修饰符,当我想要在导航栏中返回功能时使用它们。

后退按钮:

import SwiftUI

struct BackButton: View 
  @Environment(\.dismiss) var dismiss
  
  var body: some View 
    Button(action: 
      self.dismiss()
    ) 
      HStack 
        Text(Image(systemName: "chevron.backward"))
        Text("Back")
      
      .font(myCustomFont)
      .foregroundColor(myCustomColor)
    
  

视图修饰符:

// MARK: NavigationBar Back button
private struct NavigationBarBackButton:ViewModifier 
  public func body(content: Content) -> some View 
    content
      .navigationBarBackButtonHidden(true)
      .toolbar 
        ToolbarItem(id: "navigationBarBackButton", placement: .navigationBarLeading, showsByDefault: true) 
          BackButton()
        
      
  


extension View 
  public func navigationBarBackButton() -> some View 
    self.modifier(NavigationBarBackButton())
  

示例用法:

import SwiftUI

struct ContentView:View 
  var body: some View 
    NavigationView 
      ViewA()
        .navigationBarBackButton()
    
  

【讨论】:

以上是关于SwiftUI NavigationBar 后退按钮在使用自定义字体时抱怨图标缩放的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 视图中包装 UIBarButtonItem?

导航栏:“隐藏”标题,但为后续的后退按钮保留它

iOS 7 NavigationBar 后退按钮自定义图像没有标签

NavigationBar 后退按钮奇怪的行为并且不起作用

SwiftUI 移除 NavigationBar 底部边框

SwiftUI 使用 NavigationBar 显示/隐藏标题问题