-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
This duplicates this ticket:
#4832 (comment)
Specifically for RNV 6.19.0
When going to full screen, a tiny swipe that isn't enough to close the video gets it stuck in a state where the are no screen controls and swiping no longer works. The only solution is to shutdown the app and start over.
Seems to be a UIKit bug in iOS 26 affecting AVPlayerViewController.
This is my solution which seems to work.
Fix: Patch react-native-video 6.19.0 — dismiss/re-present recovery for iOS 26
react-native-video+6.19.0.patch
Three files changed:
RCTVideoPlayerViewController.swift — Removed the viewDidDisappear override. This was firing dismiss callbacks (videoPlayerViewControllerWillDismiss / DidDismiss) on cancelled swipe gestures in iOS 26, causing the JS and native state to desync. Fullscreen dismissal is now handled exclusively through AVPlayerViewControllerDelegate methods, which is the Apple-recommended approach and what react-native-video v7 uses.
RCTVideo.swift — Moved the fullscreen teardown logic (resetting _fullscreenPlayerPresented, nullifying _playerViewController, removing observers, etc.) from the old viewDidDisappear-triggered path into handleDidExitFullScreen(). This method only fires when the AVPlayerViewControllerDelegate's transition coordinator confirms the dismiss was committed (!context.isCancelled). Observer removal was also moved here from handleWillExitFullScreen — removing observers during willExit was premature since the transition might be cancelled.
RCTPlayerObserver.swift — Added iOS 26 cancelled dismiss recovery. When the transition coordinator reports isCancelled: YES, the player view controller is dismissed and immediately re-presented (both non-animated) to force UIKit to create a fresh window and gesture recognizer state. This is necessary because iOS 26 has a UIKit bug where the system gesture window's touch targets become nil after a cancelled AVPlayerViewController dismiss transition. A re-entry guard (_isRecoveringFromCancelledDismiss) prevents the recovery from looping, since the re-present can itself trigger another cancelled transition callback. Playback position and play/pause state are preserved across the recovery.
With this solution in place, the user experiences a brief flash during the dismiss/re-present recovery on a partial swipe, but the player remains fully functional afterward — controls work, swipe-to-dismiss works, and subsequent partial swipes also recover correctly.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status