From e838409c0368bb2d1dd33be8679602e5560196ae Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 19 Oct 2026 20:09:59 +0100 Subject: [PATCH] Present the camera and photo pickers over sheets on iOS The pickers were presented from the window's root view controller, which can't present while it's already presenting something. So when an app opened the camera or the photo library from a sheet, nothing happened. They now present from the topmost view controller, as the browser plugin does. Co-Authored-By: Claude Opus 5.5 --- resources/ios/CameraFunctions.swift | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/resources/ios/CameraFunctions.swift b/resources/ios/CameraFunctions.swift index 9e977fa..27e0468 100644 --- a/resources/ios/CameraFunctions.swift +++ b/resources/ios/CameraFunctions.swift @@ -7,6 +7,19 @@ import Photos import CoreLocation import ImageIO +/// The view controller to present a picker from: the topmost one, since the root +/// view controller can't present while it's already presenting something, such +/// as a sheet the app is showing. Presenting from it there does nothing at all. +private func topViewController(from root: UIViewController) -> UIViewController { + var top = root + + while let presented = top.presentedViewController, !presented.isBeingDismissed { + top = presented + } + + return top +} + // MARK: - Camera Function Namespace /// Functions related to camera operations @@ -115,7 +128,7 @@ enum CameraFunctions { picker.cameraCaptureMode = .photo picker.delegate = CameraPhotoDelegate.shared - rootVC.present(picker, animated: true) + topViewController(from: rootVC).present(picker, animated: true) } } } @@ -273,7 +286,7 @@ enum CameraFunctions { } picker.delegate = CameraVideoDelegate.shared - rootVC.present(picker, animated: true) + topViewController(from: rootVC).present(picker, animated: true) } } } @@ -852,7 +865,7 @@ final class CameraGalleryManager: NSObject { let picker = PHPickerViewController(configuration: configuration) picker.delegate = self - rootVC.present(picker, animated: true) + topViewController(from: rootVC).present(picker, animated: true) } }