Skip to content

fix(share): present share sheet from the topmost view controller on iOS - #2574

Open
mdrbohlav wants to merge 1 commit into
ionic-team:mainfrom
mdrbohlav:fix/share-ios-present-from-topmost-vc
Open

fix(share): present share sheet from the topmost view controller on iOS#2574
mdrbohlav wants to merge 1 commit into
ionic-team:mainfrom
mdrbohlav:fix/share-ios-present-from-topmost-vc

Conversation

@mdrbohlav

@mdrbohlav mdrbohlav commented Aug 3, 2026

Copy link
Copy Markdown

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:

if self?.bridge?.viewController?.presentedViewController != nil {
    call.reject("Can't share while sharing is in progress")
    return
}

presentedViewController != nil is 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 secondary WKWebView, 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.viewController cannot present while it already has a presentedViewController, 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.java tracks a real flag - isPresenting, set before startActivityForResult and reset in activityResult - 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 UIActivityViewController is actually in it, and present from the topmost view controller. When nothing is presented, presenter resolves to bridge.viewController and behaviour is identical to today.

iPad popover

setCenteredPopover (CAPPlugin.m) hardcodes sourceView to bridge.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 with permittedArrowDirections = [] - the same result setCenteredPopover produces, relative to the correct view.

Change Type

  • Fix
  • Feature
  • Refactor
  • Breaking Change
  • Documentation
  • Other (CI, chores, etc.)

Platforms Affected

  • Android
  • iOS
  • Web

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
mdrbohlav force-pushed the fix/share-ios-present-from-topmost-vc branch from 19ef5d3 to 23d4391 Compare August 3, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant