diff --git a/apple/RNCWebView.h b/apple/RNCWebView.h index a0f8549d7..2b6e23aac 100644 --- a/apple/RNCWebView.h +++ b/apple/RNCWebView.h @@ -62,6 +62,8 @@ @property (nonatomic, assign) BOOL directionalLockEnabled; @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; +@property (nonatomic, assign) BOOL pullToRefreshEnabled; +@property (nonatomic, weak) UIRefreshControl * refreshControl; #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ @property (nonatomic, assign) WKContentMode contentMode; @@ -75,5 +77,7 @@ - (void)goBack; - (void)reload; - (void)stopLoading; +- (void)addPullToRefreshControl; +- (void)pullToRefresh:(UIRefreshControl *)refreshControl; @end diff --git a/apple/RNCWebView.m b/apple/RNCWebView.m index a595fd70f..bdbce7ea4 100644 --- a/apple/RNCWebView.m +++ b/apple/RNCWebView.m @@ -275,9 +275,13 @@ - (void)didMoveToWindow _webView.UIDelegate = self; _webView.navigationDelegate = self; #if !TARGET_OS_OSX + if (_pullToRefreshEnabled) { + [self addPullToRefreshControl]; + } _webView.scrollView.scrollEnabled = _scrollEnabled; _webView.scrollView.pagingEnabled = _pagingEnabled; - _webView.scrollView.bounces = _bounces; + //For UIRefreshControl to work correctly, the bounces should always be true + _webView.scrollView.bounces = _pullToRefreshEnabled || _bounces; _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator; _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator; _webView.scrollView.directionalLockEnabled = _directionalLockEnabled; @@ -308,7 +312,6 @@ - (void)setAllowsBackForwardNavigationGestures:(BOOL)allowsBackForwardNavigation _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures; } - - (void)removeFromSuperview { if (_webView) { @@ -1156,6 +1159,35 @@ - (void)reload } } +- (void)addPullToRefreshControl +{ + UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; + _refreshControl = refreshControl; + [_webView.scrollView addSubview: refreshControl]; + [refreshControl addTarget:self action:@selector(pullToRefresh:) forControlEvents: UIControlEventValueChanged]; +} + +- (void)pullToRefresh:(UIRefreshControl *)refreshControl +{ + [self reload]; + [refreshControl endRefreshing]; +} + +#if !TARGET_OS_OSX +- (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled +{ + _pullToRefreshEnabled = pullToRefreshEnabled; + + if (pullToRefreshEnabled) { + [self addPullToRefreshControl]; + } else { + [_refreshControl removeFromSuperview]; + } + + [self setBounces:_bounces]; +} +#endif // !TARGET_OS_OSX + - (void)stopLoading { [_webView stopLoading]; @@ -1165,11 +1197,11 @@ - (void)stopLoading - (void)setBounces:(BOOL)bounces { _bounces = bounces; - _webView.scrollView.bounces = bounces; + //For UIRefreshControl to work correctly, the bounces should always be true + _webView.scrollView.bounces = _pullToRefreshEnabled || bounces; } #endif // !TARGET_OS_OSX - - (void)setInjectedJavaScript:(NSString *)source { _injectedJavaScript = source; diff --git a/apple/RNCWebViewManager.m b/apple/RNCWebViewManager.m index 35c55a71a..2d1125c83 100644 --- a/apple/RNCWebViewManager.m +++ b/apple/RNCWebViewManager.m @@ -103,6 +103,10 @@ - (RCTUIView *)view }]; } +RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebView) { + view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json]; +} + RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) { view.bounces = json == nil ? true : [RCTConvert BOOL: json]; } diff --git a/docs/Reference.md b/docs/Reference.md index 4d4f44cab..8740d9d03 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -67,6 +67,7 @@ This document lays out the current public properties and methods for the React N - [`allowsLinkPreview`](Reference.md#allowsLinkPreview) - [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled) - [`textZoom`](Reference.md#textZoom) +- [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled) - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch) - [`onFileDownload`](Reference.md#onFileDownload) @@ -1193,6 +1194,16 @@ Example: `` +--- + +### `pullToRefreshEnabled`[⬆](#props-index) + +Boolean value that determines whether a pull to refresh gesture is available in the `WebView`. The default value is `false`. If `true`, sets `bounces` automatically to `true`. + +| Type | Required | Platform | +| ------- | -------- | -------- | +| boolean | No | iOS | + ### `ignoreSilentHardwareSwitch`[⬆](#props-index) (ios only) diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 05223ac37..df880159b 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -417,7 +417,7 @@ export interface IOSWebViewProps extends WebViewSharedProps { /** * Defaults to `recommended`, which loads mobile content on iPhone * and iPad Mini but desktop content on other iPads. - * + * * Possible values are: * - `'recommended'` * - `'mobile'` @@ -551,6 +551,15 @@ export interface IOSWebViewProps extends WebViewSharedProps { */ injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; + /** + * Boolean value that determines whether a pull to refresh gesture is + * available in the `WebView`. The default value is `false`. + * If `true`, sets `bounces` automatically to `true` + * @platform ios + * + */ + pullToRefreshEnabled?: boolean; + /** * Function that is invoked when the client needs to download a file. *