fix(share): present share sheet from the topmost view controller on iOS - #2574
Open
mdrbohlav wants to merge 1 commit into
Open
fix(share): present share sheet from the topmost view controller on iOS#2574mdrbohlav wants to merge 1 commit into
mdrbohlav wants to merge 1 commit into
Conversation
On iOS, share() rejected with "Can't share while sharing is in progress" whenever any view controller was presented over the bridge view controller, not only when a share sheet was already open. Any app that presents a native modal over the webview - an in-app browser, a camera or document picker, a secondary WKWebView, a native auth session - could not share while that modal was on screen, and the error reported a share state that did not exist. Removing the guard alone is not enough: bridge.viewController cannot present while it already has a presentedViewController, so UIKit logs "Attempt to present ... which is already presenting ..." and no sheet appears. Walk the presentation chain and reject only when a UIActivityViewController is found in it, then present from the topmost view controller. Anchor the iPad popover to that controller's own view, since setCenteredPopover anchors to bridge.viewController.view, which is not in the presenter's hierarchy when presenting from a different view controller. Behaviour is unchanged when nothing is presented. This aligns iOS with the Android implementation, which tracks an isPresenting flag and already rejects only during an actual share.
mdrbohlav
force-pushed
the
fix/share-ios-present-from-topmost-vc
branch
from
August 3, 2026 15:30
19ef5d3 to
23d4391
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On iOS,
Share.share()rejects with"Can't share while sharing is in progress"whenever any view controller is presented over the bridge view controller - not only when a share sheet is open.share/ios/Sources/SharePlugin/SharePlugin.swift:presentedViewController != nilis true for any presented view controller. The guard tests presentation state but reports it as share state, so any app presenting a native modal over the webview - an in-app browser, a camera or document picker, a secondaryWKWebView, a native auth session — cannot share while that modal is on screen, and the error points developers at a stuck share that never existed.Removing the guard alone would not fix it:
bridge.viewControllercannot present while it already has apresentedViewController, so UIKit logs "Attempt to present … which is already presenting …" and no sheet appears. The sheet has to be presented from the topmost view controller.Inconsistent with Android
share/android/src/main/java/com/capacitorjs/plugins/share/SharePlugin.javatracks a real flag -isPresenting, set beforestartActivityForResultand reset inactivityResult- and rejects only during an actual share. Android shares fine over a presented activity; iOS does not. Both platforms emit the same error string for different conditions, so identical app code behaves differently per platform. This PR makes iOS match Android.Fix
Walk the presentation chain, reject only if a
UIActivityViewControlleris actually in it, and present from the topmost view controller. When nothing is presented,presenterresolves tobridge.viewControllerand behaviour is identical to today.iPad popover
setCenteredPopover(CAPPlugin.m) hardcodessourceViewtobridge.viewController.view. When presenting from a different view controller that view is not in the presenter's hierarchy, which is invalid for a popover. The popover is therefore anchored to the presenting controller's own view, centered withpermittedArrowDirections = []- the same resultsetCenteredPopoverproduces, relative to the correct view.Change Type
Platforms Affected