Есть ли лучший способ моделировать плавающую панель инструментов в SwiftUI, которая реагирует на изменения @ EnvironmentObject без повторного рендеринга всего приложения? - PullRequest
2 голосов
/ 06 апреля 2020

Я создаю приложение, используя SwiftUI, где представление root представляет собой представление с четырьмя вкладками. Одной из функций приложения является возможность проигрывать подкаст во время просмотра приложения. Как только звук начнет воспроизводиться, я хочу показать «мини-плеер» с простым управлением запуска / остановки, а также отслеживать текущий прогресс.

Для отслеживания прогресса у меня есть @EnvironmentObject, введенный в представление root, которое публикует обновления времени воспроизведения и т. Д. c. так что мини-плеер может ответить. Проблема, которую я обнаружил, состоит в том, что каждый раз, когда значение времени воспроизведения изменяется, каждая вкладка перерисовывается (что плохо). Вот некоторый [упрощенный] код:

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, но я использовал читатель Geometry на ContentView, чтобы помочь позиционировать плавающий MiniPlayer. showMiniPlayer - единственная переменная из PlayerManger, с которой я сталкиваюсь в ContentView ... все остальное автономно в MiniPlayer Представлении.

1 Ответ

0 голосов
/ 07 апреля 2020

Я где-то читал, что вы можете использовать .id (), чтобы идентифицировать представление таким образом, чтобы предотвратить постоянное обновление sh. Что-то вроде:

@State private var vid = 0

, затем присоедините ".id (vid)" к вашему TabView или MiniPlayerView.

Дайте нам знать, если это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...