Wrong Share modal position on tablet (iPad OS)
Describe the bug When I click on the button that triggers share action, on iPad OS (and, perhaps, on Android tablets?) the Share modal window appears, but it's located far from the actual button, and there is no way to specify position.
To Reproduce Create Scaffold with action button that triggers Share action with this plugin. Run on iPad. Click on the button (which is on the top right side), and observe Share modal window appear in the top left corner.
Expected behavior Share modal window appears close to the button that triggered the action.
Screenshots

Additional context In the official Share plugin they have parameter for specifying the origin. It worked fine for me, when I was using that plugin: https://github.com/flutter/plugins/blob/master/packages/share/example/lib/main.dart#L69
Builder(
builder: (BuildContext context) {
return RaisedButton(
child: const Text('Share'),
onPressed: text.isEmpty
? null
: () {
// A builder is used to retrieve the context immediately
// surrounding the RaisedButton.
//
// The context's `findRenderObject` returns the first
// RenderObject in its descendent tree when it's not
// a RenderObjectWidget. The RaisedButton's RenderObject
// has its position and size after it's built.
final RenderBox box = context.findRenderObject();
Share.share(text,
subject: subject,
sharePositionOrigin:
box.localToGlobal(Offset.zero) &
box.size);
},
);
},
I believe iOS 13.2+ also messes up the placement of this, on iPad this share popover view is off of the screen completely. All of my new apps are being rejected because of this new placement issue.
See https://github.com/esysberlin/esys-flutter-share/issues/46 which is the same bug.
As a crude workaround, I've modified the iOS source code like this:
....
// set up activity view controller
setupAndShow(activityItems)
}
private func setupAndShow(_ activityItems: [Any]) {
let activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
let controller = UIApplication.shared.keyWindow!.rootViewController as! FlutterViewController
if let popover = activityViewController.popoverPresentationController {
popover.sourceView = controller.view
let bounds = controller.view.bounds
popover.sourceRect = CGRect(x: bounds.width - 96, y: 20, width: 48, height: 48)
}
controller.show(activityViewController, sender: self)
}
For a real fix, the Flutter part of the plugin would need to compute the screen position of the triggering button and pass this position to the native part.
i made a pull request: #54
It works on my iPad (i don't have an iPhone).
While it is not merge you can use my repo if it works for you: pubsec.yaml:
esys_flutter_share:
git:
url: git://github.com/neckaros/esys-flutter-share.git
Look it example to see how to set point of origin (@ sma i reused your points if we are on iPad and origin is not set so that it at least appear on screen (top right corner)) https://github.com/neckaros/esys-flutter-share/blob/master/example/lib/main.dart
children: <Widget>[
Builder(
builder: (BuildContext context) => MaterialButton(
child: Text('Share text'),
onPressed: () async => await _shareText(context),
),
),...
...
Rect rect(BuildContext context) {
final RenderBox box = context.findRenderObject();
return box.localToGlobal(Offset.zero) & box.size;
}
Future<void> _shareText(BuildContext context) async {
try {
Share.text('my text title',
'This is my text to share with other applications.', 'text/plain', sharePositionOrigin: rect(context),);
} catch (e) {
print('error: $e');
}
}