From a06f513892f8d787726adb21f8363099e2a658fc Mon Sep 17 00:00:00 2001 From: Ben Bieker Date: Wed, 4 Dec 2019 11:21:58 +0100 Subject: [PATCH] [webview_flutter] add gesture navigation for iOS This introduces a boolean for the allowsBackForwardNavigationGestures setting of the WKWebView in iOS. It has no effect on Android. --- packages/webview_flutter/CHANGELOG.md | 1 + .../webview_flutter/example/lib/main.dart | 1 + .../test_driver/webview_flutter_e2e.dart | 26 +++++++++++++++++++ .../ios/Classes/FlutterWebView.m | 4 +++ .../lib/platform_interface.dart | 8 +++++- .../lib/src/webview_method_channel.dart | 2 ++ .../webview_flutter/lib/webview_flutter.dart | 10 +++++++ packages/webview_flutter/pubspec.yaml | 2 +- .../test/webview_flutter_test.dart | 6 ++++- 9 files changed, 57 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 1d4ce005146f..d8c4307666c9 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.3.18 * Add support for onPageStarted event. +* Add setting for iOS to allow gesture based navigation. ## 0.3.17 diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 20520d1532a4..b37c73de9e11 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -74,6 +74,7 @@ class _WebViewExampleState extends State { onPageFinished: (String url) { print('Page finished loading: $url'); }, + allowsBackForwardNavigationGestures: true, ); }), floatingActionButton: favoriteButton(), diff --git a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart index 373e65c6cbdd..314944df5775 100644 --- a/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart +++ b/packages/webview_flutter/example/test_driver/webview_flutter_e2e.dart @@ -652,6 +652,32 @@ void main() { expect(currentUrl, 'https://www.google.com/'); }); }); + + testWidgets('launches with allowsBackForwardNavigationGestures on iOS', + (WidgetTester tester) async { + final Completer controllerCompleter = + Completer(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: SizedBox( + width: 400, + height: 300, + child: WebView( + key: GlobalKey(), + initialUrl: 'https://flutter.dev/', + allowsBackForwardNavigationGestures: true, + onWebViewCreated: (WebViewController controller) { + controllerCompleter.complete(controller); + }, + ), + ), + ), + ); + final WebViewController controller = await controllerCompleter.future; + final String currentUrl = await controller.currentUrl(); + expect(currentUrl, 'https://flutter.dev/'); + }); } // JavaScript booleans evaluate to different string values on Android and iOS. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 60fa24052038..412587848f92 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -260,6 +260,10 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"userAgent"]) { NSString* userAgent = settings[key]; [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; + } else if ([key isEqualToString:@"allowsBackForwardNavigationGestures"]) { + NSNumber* allowsBackForwardNavigationGestures = settings[key]; + _webView.allowsBackForwardNavigationGestures = + [allowsBackForwardNavigationGestures boolValue]; } else { [unknownKeys addObject:key]; } diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index a3af47a5c714..a847cf98614a 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -232,6 +232,7 @@ class WebSettings { this.hasNavigationDelegate, this.debuggingEnabled, @required this.userAgent, + this.allowsBackForwardNavigationGestures, }) : assert(userAgent != null); /// The JavaScript execution mode to be used by the webview. @@ -255,9 +256,14 @@ class WebSettings { /// See also [WebView.userAgent]. final WebSetting userAgent; + /// Whether to allow swipe based navigation in iOS. + /// + /// See also: [WebView.allowsBackForwardNavigationGestures] + final bool allowsBackForwardNavigationGestures; + @override String toString() { - return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent,)'; + return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent, allowsBackForwardNavigationGestures: $allowsBackForwardNavigationGestures)'; } } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index ad5a81e98ef5..c299b7a3bdbb 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -137,6 +137,8 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); + _addIfNonNull('allowsBackForwardNavigationGestures', + settings.allowsBackForwardNavigationGestures); _addSettingIfPresent('userAgent', settings.userAgent); return map; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index a57e2e13bdba..17a35ab5cb73 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -151,6 +151,7 @@ class WebView extends StatefulWidget { this.userAgent, this.initialMediaPlaybackPolicy = AutoMediaPlaybackPolicy.require_user_action_for_all_media_types, + this.allowsBackForwardNavigationGestures, }) : assert(javascriptMode != null), assert(initialMediaPlaybackPolicy != null), super(key: key); @@ -311,6 +312,13 @@ class WebView extends StatefulWidget { /// The default policy is [AutoMediaPlaybackPolicy.require_user_action_for_all_media_types]. final AutoMediaPlaybackPolicy initialMediaPlaybackPolicy; + /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations. + /// + /// This only works on iOS. + /// + /// By default `allowsBackForwardNavigationGestures` is false. + final bool allowsBackForwardNavigationGestures; + @override State createState() => _WebViewState(); } @@ -384,6 +392,8 @@ WebSettings _webSettingsFromWidget(WebView widget) { hasNavigationDelegate: widget.navigationDelegate != null, debuggingEnabled: widget.debuggingEnabled, userAgent: WebSetting.of(widget.userAgent), + allowsBackForwardNavigationGestures: + widget.allowsBackForwardNavigationGestures, ); } diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index 236d591aea61..e5efebbe8d85 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.17 +version: 0.3.18 author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 1772df3fa815..3b9566b11172 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -822,6 +822,7 @@ void main() { await tester.pumpWidget( const WebView( initialUrl: 'https://youtube.com', + allowsBackForwardNavigationGestures: true, ), ); @@ -837,6 +838,7 @@ void main() { hasNavigationDelegate: false, debuggingEnabled: false, userAgent: WebSetting.of(null), + allowsBackForwardNavigationGestures: true, ), // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals @@ -1193,7 +1195,9 @@ class MatchesWebSettings extends Matcher { _webSettings.hasNavigationDelegate == webSettings.hasNavigationDelegate && _webSettings.debuggingEnabled == webSettings.debuggingEnabled && - _webSettings.userAgent == webSettings.userAgent; + _webSettings.userAgent == webSettings.userAgent && + _webSettings.allowsBackForwardNavigationGestures == + webSettings.allowsBackForwardNavigationGestures; } }