diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 32ccc7c665a2..f87091e3aa89 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.19+5 + +* On iOS, always keep contentInsets of the WebView to be 0. +* Fix XCTest case to follow XCTest naming convention. + ## 0.3.19+4 * On iOS, fix the scroll view content inset is automatically adjusted. After the fix, the content position of the WebView is customizable by Flutter. diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.h b/packages/webview_flutter/ios/Classes/FlutterWebView.h index 08e6b8ab53a8..627790186dac 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.h +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.h @@ -21,4 +21,12 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithMessenger:(NSObject*)messenger; @end +/** + * The WkWebView used for the plugin. + * + * This class overrides some methods in `WKWebView` to serve the needs for the plugin. + */ +@interface FLTWKWebView : WKWebView +@end + NS_ASSUME_NONNULL_END diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index b1fc143fed64..20aad2c593ff 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -34,8 +34,30 @@ - (instancetype)initWithMessenger:(NSObject*)messenger { @end +@implementation FLTWKWebView + +- (void)setFrame:(CGRect)frame { + [super setFrame:frame]; + self.scrollView.contentInset = UIEdgeInsetsZero; + // We don't want the contentInsets to be adjusted by iOS, flutter should always take control of + // webview's contentInsets. + // self.scrollView.contentInset = UIEdgeInsetsZero; + if (@available(iOS 11, *)) { + // Above iOS 11, adjust contentInset to compensate the adjustedContentInset so the sum will + // always be 0. + if (UIEdgeInsetsEqualToEdgeInsets(self.scrollView.adjustedContentInset, UIEdgeInsetsZero)) { + return; + } + UIEdgeInsets insetToAdjust = self.scrollView.adjustedContentInset; + self.scrollView.contentInset = UIEdgeInsetsMake(-insetToAdjust.top, -insetToAdjust.left, + -insetToAdjust.bottom, -insetToAdjust.right); + } +} + +@end + @implementation FLTWebViewController { - WKWebView* _webView; + FLTWKWebView* _webView; int64_t _viewId; FlutterMethodChannel* _channel; NSString* _currentUrl; @@ -69,7 +91,7 @@ - (instancetype)initWithFrame:(CGRect)frame [self updateAutoMediaPlaybackPolicy:args[@"autoMediaPlaybackPolicy"] inConfiguration:configuration]; - _webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration]; + _webView = [[FLTWKWebView alloc] initWithFrame:frame configuration:configuration]; _navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel]; _webView.navigationDelegate = _navigationDelegate; __weak __typeof__(self) weakSelf = self; diff --git a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m index a545fd75c78c..45fa5214c712 100644 --- a/packages/webview_flutter/ios/Tests/FLTWebViewTests.m +++ b/packages/webview_flutter/ios/Tests/FLTWebViewTests.m @@ -7,6 +7,8 @@ @import XCTest; @import webview_flutter; +static bool feq(CGFloat a, CGFloat b) { return fabs(b - a) < FLT_EPSILON; } + @interface FLTWebViewTests : XCTestCase @property(strong, nonatomic) NSObject *mockBinaryMessenger; @@ -20,7 +22,7 @@ - (void)setUp { self.mockBinaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); } -- (void)canInitFLTWebViewController { +- (void)testCanInitFLTWebViewController { FLTWebViewController *controller = [[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400) viewIdentifier:1 @@ -29,7 +31,7 @@ - (void)canInitFLTWebViewController { XCTAssertNotNil(controller); } -- (void)canInitFLTWebViewFactory { +- (void)testCanInitFLTWebViewFactory { FLTWebViewFactory *factory = [[FLTWebViewFactory alloc] initWithMessenger:self.mockBinaryMessenger]; XCTAssertNotNil(factory); @@ -50,7 +52,7 @@ - (void)webViewContentInsetBehaviorShouldBeNeverOnIOS11 { } } -- (void)webViewScrollIndicatorAticautomaticallyAdjustsScrollIndicatorInsetsShouldbeNoOnIOS13 { +- (void)testWebViewScrollIndicatorAticautomaticallyAdjustsScrollIndicatorInsetsShouldbeNoOnIOS13 { if (@available(iOS 13, *)) { FLTWebViewController *controller = [[FLTWebViewController alloc] initWithFrame:CGRectMake(0, 0, 300, 400) @@ -64,4 +66,24 @@ - (void)webViewScrollIndicatorAticautomaticallyAdjustsScrollIndicatorInsetsShoul } } +- (void)testContentInsetsSumAlwaysZeroAfterSetFrame { + FLTWKWebView *webView = [[FLTWKWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 400)]; + webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, 300, 0); + XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(webView.scrollView.contentInset, UIEdgeInsetsZero)); + webView.frame = CGRectMake(0, 0, 300, 200); + XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(webView.scrollView.contentInset, UIEdgeInsetsZero)); + XCTAssertTrue(CGRectEqualToRect(webView.frame, CGRectMake(0, 0, 300, 200))); + + if (@available(iOS 11, *)) { + // After iOS 11, we need to make sure the contentInset compensates the adjustedContentInset. + UIScrollView *partialMockScrollView = OCMPartialMock(webView.scrollView); + UIEdgeInsets insetToAdjust = UIEdgeInsetsMake(0, 0, 300, 0); + OCMStub(partialMockScrollView.adjustedContentInset).andReturn(insetToAdjust); + XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(webView.scrollView.contentInset, UIEdgeInsetsZero)); + webView.frame = CGRectMake(0, 0, 300, 100); + XCTAssertTrue(feq(webView.scrollView.contentInset.bottom, -insetToAdjust.bottom)); + XCTAssertTrue(CGRectEqualToRect(webView.frame, CGRectMake(0, 0, 300, 100))); + } +} + @end diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index e528e8d36994..bbe6107678fe 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.19+4 +version: 0.3.19+5 homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter environment: