From 60a52bc12e04a1206824dadd8512a4c679522fec Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sun, 14 Aug 2022 18:59:04 +0200 Subject: [PATCH] tvOS layout improvements --- Model/Player/PlayerModel.swift | 24 ++++++++++++++++-------- Shared/Player/Controls/TVControls.swift | 10 ---------- Shared/Player/PlayerBackendView.swift | 19 ++++++++++++++++++- Shared/YatteeApp.swift | 4 +++- tvOS/TVNavigationView.swift | 16 +++++++++++++++- 5 files changed, 52 insertions(+), 21 deletions(-) diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 33b1af45..39c0df4c 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -40,7 +40,12 @@ final class PlayerModel: ObservableObject { var mpvPlayerView = MPVPlayerView() - @Published var presentingPlayer = true { didSet { handlePresentationChange() } } + #if os(iOS) + static let presentingPlayerDefault = true + #else + static let presentingPlayerDefault = false + #endif + @Published var presentingPlayer = presentingPlayerDefault { didSet { handlePresentationChange() } } @Published var activeBackend = PlayerBackendType.mpv var avPlayerBackend: AVPlayerBackend! @@ -63,7 +68,9 @@ final class PlayerModel: ObservableObject { } @Published var playerSize: CGSize = .zero { didSet { - backend.setSize(playerSize.width, playerSize.height) + #if !os(tvOS) + backend.setSize(playerSize.width, playerSize.height) + #endif }} @Published var aspectRatio = VideoPlayerView.defaultAspectRatio @Published var stream: Stream? @@ -880,13 +887,14 @@ final class PlayerModel: ObservableObject { mpvBackend.setVideoToAuto() } - func updateAspectRatio() { - guard aspectRatio != backend.aspectRatio else { return } + #if !os(tvOS) + guard aspectRatio != backend.aspectRatio else { return } - DispatchQueue.main.async { [weak self] in - guard let self = self else { return } - self.aspectRatio = self.backend.aspectRatio - } + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + self.aspectRatio = self.backend.aspectRatio + } + #endif } } diff --git a/Shared/Player/Controls/TVControls.swift b/Shared/Player/Controls/TVControls.swift index d98f1e41..500f2469 100644 --- a/Shared/Player/Controls/TVControls.swift +++ b/Shared/Player/Controls/TVControls.swift @@ -10,8 +10,6 @@ struct TVControls: UIViewRepresentable { @State private var controlsArea = UIView() func makeUIView(context: Context) -> UIView { - let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap(sender:))) - let leftSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:))) leftSwipe.direction = .left @@ -24,7 +22,6 @@ struct TVControls: UIViewRepresentable { let downSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:))) downSwipe.direction = .down - controlsArea.addGestureRecognizer(tapGesture) controlsArea.addGestureRecognizer(leftSwipe) controlsArea.addGestureRecognizer(rightSwipe) controlsArea.addGestureRecognizer(upSwipe) @@ -62,16 +59,9 @@ struct TVControls: UIViewRepresentable { fatalError("init(coder:) has not been implemented") } - @objc func handleTap(sender: UITapGestureRecognizer) { - let location = sender.location(in: view) - model.reporter.send("tap \(location)") - print("tap \(location)") - } - @objc func handleSwipe(sender: UISwipeGestureRecognizer) { let location = sender.location(in: view) model.reporter.send("swipe \(location)") - print("swipe \(location)") } } } diff --git a/Shared/Player/PlayerBackendView.swift b/Shared/Player/PlayerBackendView.swift index 8348b8e1..ec889b1c 100644 --- a/Shared/Player/PlayerBackendView.swift +++ b/Shared/Player/PlayerBackendView.swift @@ -33,7 +33,6 @@ struct PlayerBackendView: View { .onAppear { player.playerSize = proxy.size } .onChange(of: proxy.size) { _ in player.playerSize = proxy.size } .onChange(of: player.controls.presentingOverlays) { _ in player.playerSize = proxy.size } - .onChange(of: player.aspectRatio) { _ in player.playerSize = proxy.size } }) #if os(iOS) .padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0) @@ -46,6 +45,8 @@ struct PlayerBackendView: View { .padding(.top, controlsTopPadding) .padding(.bottom, controlsBottomPadding) #endif + #else + hiddenControlsButton #endif } #if os(iOS) @@ -82,6 +83,22 @@ struct PlayerBackendView: View { } } #endif + + #if os(tvOS) + private var hiddenControlsButton: some View { + VStack { + Button { + player.controls.show() + } label: { + EmptyView() + } + .offset(y: -100) + .buttonStyle(.plain) + .background(Color.clear) + .foregroundColor(.clear) + } + } + #endif } struct PlayerBackendView_Previews: PreviewProvider { diff --git a/Shared/YatteeApp.swift b/Shared/YatteeApp.swift index d97ec992..f53bc298 100644 --- a/Shared/YatteeApp.swift +++ b/Shared/YatteeApp.swift @@ -238,6 +238,8 @@ struct YatteeApp: App { player.updateRemoteCommandCenter() #endif - player.presentingPlayer = false + if player.presentingPlayer { + player.presentingPlayer = false + } } } diff --git a/tvOS/TVNavigationView.swift b/tvOS/TVNavigationView.swift index 8d72d57d..4e88c3e2 100644 --- a/tvOS/TVNavigationView.swift +++ b/tvOS/TVNavigationView.swift @@ -10,6 +10,8 @@ struct TVNavigationView: View { @Default(.visibleSections) private var visibleSections + @State private var playerInitialized = false + var body: some View { NavigationView { TabView(selection: navigation.tabSelectionBinding) { @@ -52,11 +54,11 @@ struct TVNavigationView: View { .tag(TabSelection.search) SettingsView() - .navigationBarHidden(true) .tabItem { Image(systemName: "gear") } .tag(TabSelection.settings) } } + .background(videoPlayerInitialize) .fullScreenCover(isPresented: $navigation.presentingAddToPlaylist) { if let video = navigation.videoToAddToPlaylist { AddToPlaylistView(video: video) @@ -76,6 +78,18 @@ struct TVNavigationView: View { } } } + + @ViewBuilder var videoPlayerInitialize: some View { + if !playerInitialized { + VideoPlayerView() + .scaleEffect(0.00001) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + playerInitialized = true + } + } + } + } } struct TVNavigationView_Previews: PreviewProvider {