Skip to content

Commit 604dffc

Browse files
blaineamclaude
andcommitted
Fix swipe navigation blocked by controls and reduce video buffering jitter
GestureBlockerView's shouldBeRequiredToFailBy returned true unconditionally, preventing the parent navigation DragGesture from ever firing. Now cancels its own pan gesture when a large horizontal swipe is detected (>80pt, mostly horizontal), letting the SwiftUI navigation gesture through. Short drags (scrub bar, sliders) are still blocked as intended. For remote video streams, set preferredForwardBufferDuration=30 and automaticallyWaitsToMinimizeStalling=false to match VR player config. This reduces stalling on slow connections by buffering more aggressively and starting playback immediately instead of waiting for a full buffer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 31e2c47 commit 604dffc

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

‎Sources/MediaStream/WebViewVideoPlayer.swift‎

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,26 @@ private class GestureBlockerView: UIView {
6464
}
6565

6666
private func setupGesture() {
67-
let pan = UIPanGestureRecognizer(target: nil, action: nil)
67+
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
6868
pan.cancelsTouchesInView = false
6969
pan.delaysTouchesBegan = false
7070
pan.delaysTouchesEnded = false
7171
pan.delegate = self
7272
addGestureRecognizer(pan)
7373
}
74+
75+
@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
76+
// Consume small drags (scrub bar, sliders) but let large horizontal
77+
// swipes pass through to the parent navigation DragGesture.
78+
if gesture.state == .changed {
79+
let translation = gesture.translation(in: self)
80+
let horizontal = abs(translation.x)
81+
let vertical = abs(translation.y)
82+
if horizontal > 80 && horizontal > vertical * 2 {
83+
gesture.state = .cancelled
84+
}
85+
}
86+
}
7487
}
7588

7689
extension GestureBlockerView: UIGestureRecognizerDelegate {
@@ -90,6 +103,15 @@ extension GestureBlockerView: UIGestureRecognizerDelegate {
90103
}
91104

92105
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
106+
// Don't block SwiftUI's navigation DragGesture (which has minimumDistance=100).
107+
// Only block short drags that interact with controls (scrub bar, volume slider).
108+
if let pan = otherGestureRecognizer as? UIPanGestureRecognizer {
109+
let translation = pan.translation(in: pan.view)
110+
let horizontal = abs(translation.x)
111+
if horizontal > 80 {
112+
return false
113+
}
114+
}
93115
return true
94116
}
95117
}

‎Sources/MediaStream/ZoomableMediaView.swift‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,14 @@ struct ZoomableMediaView: View {
25292529
asset = AVURLAsset(url: url)
25302530
}
25312531
let playerItem = AVPlayerItem(asset: asset)
2532+
// Buffer aggressively for remote streams to reduce stalling on slow connections
2533+
if !url.isFileURL {
2534+
playerItem.preferredForwardBufferDuration = 30
2535+
}
25322536
let player = AVPlayer(playerItem: playerItem)
2537+
if !url.isFileURL {
2538+
player.automaticallyWaitsToMinimizeStalling = false
2539+
}
25332540

25342541
// Wait a moment to check if AVPlayer can load the video
25352542
do {

0 commit comments

Comments
 (0)