【问题标题】:Why does iOS Status Bar collapses because of Blur Effect since iOS 15?从 iOS 15 开始,为什么 iOS 状态栏会因为模糊效果而崩溃?
【发布时间】:2022-01-10 23:08:45
【问题描述】:

自从iOS 15 之后我遇到了一个奇怪的问题:我在App's Root View 上有一个Blur Effect,它会根据scenePhase 而变化。 在 iOS 15 发布之前,它一直运行良好。现在,每当Blur Effect 为0 时,App 的Status Bar 就会崩溃,Navigation Bar 会向上移动,不再可交互。

struct RootView: View {
    @Environment(\.scenePhase) var scenePhase
    @State private var blurRadius: CGFloat = 0

    var body: some View {
        Group {
            OtherViews()
        }
        .blur(radius: blurRadius)
        .onChange(of: scenePhase) { newValue in updateBlurRadius(newValue) }
    }

     private func updateBlurRadius(_ scenePhase: ScenePhase) {
         switch scenePhase {
             case .active : withAnimation { blurRadius = 0 }
             case .inactive: withAnimation { blurRadius = 16 }
             case .background: withAnimation { blurRadius = 16 }
             @unknown default: print("Unknown Case")
        }
    }
}

此代码适用于 iOS 14 及之前的版本。但是,由于iOS 15,出现如下bug:

  • 奇怪的是,当scenePhase 变成inactive 时,Navigation Bar 会立即跳到正确的位置。一旦scenePhase 再次变为active,它就会跳回到Status Bar 后面的顶部。
  • 此外,当将 Blur Radiusactive scenePhase 更改为 0.001 而不是 0 时,一切正常,Navigation Bar 不会跳到 Status Bar 后面。

有谁知道在使用Blur Effects 时会导致这种奇怪行为的原因是什么?

非常感谢您提前提供的帮助。

【问题讨论】:

  • 您是否尝试使用一些堆栈而不是Group
  • 你问“为什么”,所以我们不在 Apple SwiftUI 团队中(至少不是我),所以我们怎么可能回答为什么!也许您需要询问如何解决此问题。
  • @swiftPunk 是的,我的问题是如何解决这种行为。
  • @Asperi 我刚刚将Group 替换为ZStack,但这并不能解决问题。此外,组对象内部是一个if-else-statement,而不仅仅是一个视图。

标签: ios swift xcode swiftui uikit


【解决方案1】:

我遇到了这个确切的问题,但无法找到解决方法,所以我现在正在使用这个替代实现,它的作用几乎相同:

ZStack {
    // View to be blurred goes here
    Rectangle()
        .ignoresSafeArea()
        .foregroundStyle(.ultraThinMaterial)
        .opacity(/* Your condition */ ? 1 : 0)
        .animation(.easeInOut(duration: 0.2))
}

这将在您的视图上覆盖一个模糊的矩形。 所以在你的情况下:

struct RootView: View {
    @Environment(\.scenePhase) var scenePhase

    var body: some View {
        ZStack {
            OtherViews()
            Rectangle()
                .ignoresSafeArea()
                .foregroundStyle(.ultraThinMaterial)
                .opacity(scenePhase != .active ? 1 : 0)
                .animation(.easeInOut)
        }
    }
}

由于此解决方案使用了新材料,因此它仅适用于 iOS 15。您可以使用 if #available(iOS 15, *) 提供两种不同的实现,一种适用于 iOS 15+,一种适用于 iOS 14 及更早版本。

【讨论】:

    猜你喜欢
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2014-02-03
    • 1970-01-01
    • 2012-01-19
    • 2020-07-18
    • 1970-01-01
    相关资源
    最近更新 更多