首页 > 解决方案 > 是否有更好的方法在 SwiftUI 中对浮动工具栏进行建模,以响应 @EnvironmentObject 更改而无需重新渲染整个应用程序?

问题描述

我正在使用 SwiftUI 构建一个应用程序,其中根视图是一个带有四个选项卡的选项卡视图。该应用程序的一项功能是能够在您浏览该应用程序时播放播客。一旦音频开始播放,我想展示一个带有简单开始/停止控制的“迷你播放器”,并跟踪当前进度。

为了跟踪进度,我@EnvironmentObject在根视图中注入了一个,它会发布播放时间更新等,以便迷你播放器可以响应。我发现的问题是每次播放时间值发生变化时,每个选项卡都会重新渲染(这是一件坏事)这是一些[简化]代码:

struct ContentView: View {
    @EnvironmentObject var playerManager: PlayerManager
    var body: some View {
        TabView(selection: self.$selection) {
            HomeView().tag(0)
            View2().tag(1)
            View3().tag(2)
            View4().tag(3)
        }
        .overlay(
              VStack {
                  if self.playerManager.showMiniPlayer {
                        MiniPlayerView()
                  }
              }
         )
    }
}

class PodcastPlayerManager: NSObject, ObservableObject {
    @Published private(set) var elapsedTime = ElapsedTime(progress: 0, duration: 0)

    // ... Things happen that cause `elapsedTime` to update
}

init()我在函数中放了一条日志语句,View2并且它被不断地调用......这很糟糕。

我的问题是,这是否是使用 SwiftUI 对此类事物进行建模的正确/最佳方式?我也考虑过将 注入PlayerManager自身MiniPlayer,但我使用几何阅读器ContentView来帮助定位浮动MiniPlayer。是我关心showMiniPlayer的唯一变量......其他所有内容都在视图中自包含。PlayerMangerContentViewMiniPlayer

标签: swiftui

解决方案


我在某处读过您可以使用 .id() 以防止不断刷新的方式来识别视图。就像是:

@State private var vid = 0

然后将“.id(vid)”附加到您的 TabView 或 MiniPlayerView。

让我们知道这是否有效。


推荐阅读