diff --git a/stevia/lib/src/widgets/async/dialog/future_result_dialog.dart b/stevia/lib/src/widgets/async/dialog/future_result_dialog.dart index 54c80750..87d6851f 100644 --- a/stevia/lib/src/widgets/async/dialog/future_result_dialog.dart +++ b/stevia/lib/src/widgets/async/dialog/future_result_dialog.dart @@ -97,7 +97,7 @@ Future> showFutureResultDialog( /// A [FutureResultDialog]. See [showFutureValueDialog] for more details. -class FutureResultDialog extends StatelessWidget { +class FutureResultDialog extends StatefulWidget { /// The asynchronous computation. final Future> future; @@ -128,20 +128,37 @@ class FutureResultDialog extends StatelessWi this.child, }); + @override + State> createState() => _State(); + +} + +class _State extends State> { + + bool popped = false; + @override Widget build(BuildContext context) => FutureResultBuilder( - future: (_) => future, - builder: builder ?? _defaultBuilder, - failureBuilder: failureBuilder ?? _defaultBuilder, + future: (_) => widget.future, + builder: widget.builder ?? _defaultBuilder, + failureBuilder: widget.failureBuilder ?? _defaultBuilder, emptyBuilder: (context, future, child) => WillPopScope( onWillPop: () async => false, - child: emptyBuilder?.call(context, future!, child) ?? const SizedBox(), + child: widget.emptyBuilder?.call(context, future!, child) ?? const SizedBox(), ), - child: child, + child: widget.child, ); Widget _defaultBuilder(BuildContext context, dynamic value, Widget? child) { - WidgetsBinding.instance.addPostFrameCallback((_) => Navigator.of(context).pop()); + WidgetsBinding.instance.scheduleFrameCallback((_) { + // On iOS, additional frames may be rendered between the call to Navigation.pop() + // and the actual navigation. The callback needs to be latched to prevent multiple + // calls to Navigation.Pop. + if (!popped) { + popped = true; + Navigator.of(context).pop(); + } + }); return const SizedBox(); }