【问题标题】:iOS 15 SwiftUI TabView tab bar appearance doesn't update between viewsiOS 15 SwiftUI TabView 标签栏外观不会在视图之间更新
【发布时间】:2021-11-17 10:10:22
【问题描述】:

iOS 15 根据加载视图的滚动位置设置TabView 的外观。但是,这似乎不会在选项卡栏中切换的视图之间更新。如何解决此问题以便正确更新外观?

  1. 在不滚动内容的情况下打开选项卡式视图(“非滚动视图”)使用透明背景作为选项卡栏。

  2. 导航到带有滚动内容的选项卡式视图(“滚动视图”)后,将使用半透明背景。

  3. 但是,当回到“无滚动视图”时,半透明背景仍然保留,而不是被透明背景替换。

我确实注意到,当我打开控制中心或应用程序切换器并返回时,外观会正确更新。

复制:

enum Tab {
    case scroll
    case noScroll
}

struct ContentView: View {
    @State var selection: Tab = .noScroll
    
    var body: some View {
        TabView(selection: $selection) {     
            Text("Should have a transparent tab bar")
                .tabItem{ Label("No-scroll", systemImage: "xmark.circle") }
                .tag(Tab.noScroll)
            
            ScrollView {
                VStack(spacing: 10) {
                    ForEach(0..<100) {_ in
                        Text("Should have a translucent tab bar")
                    }
                }
            }
            .tabItem { Label("Scroll", systemImage: "circle") }
            .tag(Tab.scroll)
        }
    }
}

【问题讨论】:

  • @VisalRajapakse 添加了重现,谢谢
  • 尝试根据需要强行预设标签栏外观,如stackoverflow.com/a/63702533/12299030
  • @Asperi 我仍然想在透明和半透明之间更新外观,但强制设置外观会阻止这种情况。我希望拥有合适的外观,而不是定制外观。

标签: ios swift swiftui


【解决方案1】:

我遇到了类似的问题here,通过在 iOS 15 上使用它解决了

@available(iOS 15.0, *)
@NSCopying open var scrollEdgeAppearance: UITabBarAppearance?

描述 tabBar 的外观属性,当 可观察的滚动视图滚动到底部。如果没有设置, 将使用standardAppearance。

//@available(iOS 15.0, *)
//@NSCopying open var scrollEdgeAppearance: UITabBarAppearance?

let appearance: UITabBarAppearance = UITabBarAppearance()
init() {
    UITabBar.appearance().scrollEdgeAppearance = appearance
}

【讨论】:

    【解决方案2】:

    这与@cole 的答案几乎相同,但这是我的解决方案:

    .introspectTabBarController(customize: { controller in
    
                let appearance = controller.tabBar.standardAppearance
                appearance.configureWithDefaultBackground()
                appearance.backgroundColor = .red
                if #available(iOS 15.0, *) {
                    controller.tabBar.scrollEdgeAppearance = appearance
                } else {
                    controller.tabBar.standardAppearance = appearance
                }
            })
    

    使用 introspectTabBarController SwiftUI-Introspect

    【讨论】:

      【解决方案3】:
      .onAppear {
          if #available(iOS 15.0, *) {
              let appearance = UITabBarAppearance()
              UITabBar.appearance().scrollEdgeAppearance = appearance
          }
      }
      

      【讨论】:

        【解决方案4】:

        在更新到 XCode 13 和 iOS 15 后,我还遇到了一些 TabView 问题,其中栏背景颜色以及不同状态的项目文本和图标颜色。我修复它的方式:

        if #available(iOS 15, *) {
           let tabBarAppearance = UITabBarAppearance()
           tabBarAppearance.backgroundColor = backgroundColor
           tabBarAppearance.stackedLayoutAppearance.selected.titleTextAttributes = [.foregroundColor: selectedItemTextColor]
           tabBarAppearance.stackedLayoutAppearance.normal.titleTextAttributes = [.foregroundColor: unselectedItemTextColor]
           tabBar.standardAppearance = tabBarAppearance
           tabBar.scrollEdgeAppearance = tabBarAppearance
        } else {
           UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: selectedItemTextColor], for: .selected)
           UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: unselectedItemTextColor], for: .normal)
           tabBar.barTintColor = backgroundColor
         }
        

        【讨论】: