Skip to content

Commit

Permalink
Improve visibility tracking with VoiceOver enabled (#575)
Browse files Browse the repository at this point in the history
Co-authored-by: Walid Kayhal <[email protected]>
  • Loading branch information
defagos and waliid authored Sep 26, 2023
1 parent 71d83f8 commit a6c0dae
Showing 1 changed file with 40 additions and 13 deletions.
53 changes: 40 additions & 13 deletions Sources/Player/UserInterface/VisibilityTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import UIKit

/// An observable object tracking user interface visibility.
///
/// The tracker automatically turns off visibility after a delay while playing content. It also automatically turns
/// on visibility when playback is paused externally (e.g. by another app or through the control center).
/// The tracker automatically provides meaningful default behaviors, most notably to automatically turn visibility off
/// after a delay during playback. This mechanism is disabled when playback is paused or when VoiceOver is enabled.
@available(tvOS, unavailable)
public final class VisibilityTracker: ObservableObject {
private enum TriggerId {
Expand Down Expand Up @@ -75,21 +75,24 @@ public final class VisibilityTracker: ObservableObject {
private func updatePublisher(for playbackState: PlaybackState) -> AnyPublisher<Bool, Never> {
switch playbackState {
case .playing:
return togglePublisher
.prepend(isUserInterfaceHidden)
.compactMap { [weak self] isHidden -> AnyPublisher<Bool, Never>? in
guard let self else { return nil }
return Just(isHidden)
.append(autoHidePublisher(delay: delay), if: !isHidden)
}
.switchToLatest()
.eraseToAnyPublisher()
return Publishers.CombineLatest(
userInterfaceHiddenPublisher()
.prepend(isUserInterfaceHidden),
voiceOverRunningPublisher()
)
.compactMap { [weak self] isHidden, isVoiceOverRunning -> AnyPublisher<Bool, Never>? in
guard let self else { return nil }
return Just(isHidden)
.append(autoHidePublisher(delay: delay), if: !isHidden && !isVoiceOverRunning)
}
.switchToLatest()
.eraseToAnyPublisher()
case .paused:
return Publishers.Merge(togglePublisher, foregroundPublisher())
return Publishers.Merge(userInterfaceHiddenPublisher(), foregroundPublisher())
.prepend(false)
.eraseToAnyPublisher()
default:
return Publishers.Merge(togglePublisher, foregroundPublisher())
return Publishers.Merge(userInterfaceHiddenPublisher(), foregroundPublisher())
.prepend(isUserInterfaceHidden)
.eraseToAnyPublisher()
}
Expand All @@ -110,6 +113,30 @@ public final class VisibilityTracker: ObservableObject {
.map { _ in true }
.eraseToAnyPublisher()
}

private func userInterfaceHiddenPublisher() -> AnyPublisher<Bool, Never> {
Publishers.Merge(togglePublisher, voiceOverUnhidePublisher())
.eraseToAnyPublisher()
}

private func voiceOverStatusPublisher() -> AnyPublisher<Bool, Never> {
NotificationCenter.default.publisher(for: UIAccessibility.voiceOverStatusDidChangeNotification)
.map { _ in UIAccessibility.isVoiceOverRunning }
.eraseToAnyPublisher()
}

private func voiceOverRunningPublisher() -> AnyPublisher<Bool, Never> {
voiceOverStatusPublisher()
.prepend(UIAccessibility.isVoiceOverRunning)
.eraseToAnyPublisher()
}

private func voiceOverUnhidePublisher() -> AnyPublisher<Bool, Never> {
voiceOverStatusPublisher()
.filter { $0 }
.map { _ in false }
.eraseToAnyPublisher()
}
}

@available(tvOS, unavailable)
Expand Down

0 comments on commit a6c0dae

Please sign in to comment.