Browse Source

feat(iOS): Add the pull to refresh (#1265)

* Add pull to refresh support for iOS

* Add pull to refresh control removal from WebView

* Add the type and reference description about pull to refresh

* Set bounces to true when enabling pull to refresh, add references

* Add the back to props anchor to pullToRefreshEnabled
Sergei Butko 3 years ago
parent
commit
a02d88f54f
No account linked to committer's email address
5 changed files with 65 additions and 5 deletions
  1. 4
    0
      apple/RNCWebView.h
  2. 36
    4
      apple/RNCWebView.m
  3. 4
    0
      apple/RNCWebViewManager.m
  4. 11
    0
      docs/Reference.md
  5. 10
    1
      src/WebViewTypes.ts

+ 4
- 0
apple/RNCWebView.h View File

@@ -62,6 +62,8 @@
62 62
 @property (nonatomic, assign) BOOL directionalLockEnabled;
63 63
 @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch;
64 64
 @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL;
65
+@property (nonatomic, assign) BOOL pullToRefreshEnabled;
66
+@property (nonatomic, weak) UIRefreshControl * refreshControl;
65 67
 
66 68
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */
67 69
 @property (nonatomic, assign) WKContentMode contentMode;
@@ -75,5 +77,7 @@
75 77
 - (void)goBack;
76 78
 - (void)reload;
77 79
 - (void)stopLoading;
80
+- (void)addPullToRefreshControl;
81
+- (void)pullToRefresh:(UIRefreshControl *)refreshControl;
78 82
 
79 83
 @end

+ 36
- 4
apple/RNCWebView.m View File

@@ -275,9 +275,13 @@ static NSDictionary* customCertificatesForHost;
275 275
     _webView.UIDelegate = self;
276 276
     _webView.navigationDelegate = self;
277 277
 #if !TARGET_OS_OSX
278
+    if (_pullToRefreshEnabled) {
279
+        [self addPullToRefreshControl];
280
+    }
278 281
     _webView.scrollView.scrollEnabled = _scrollEnabled;
279 282
     _webView.scrollView.pagingEnabled = _pagingEnabled;
280
-    _webView.scrollView.bounces = _bounces;
283
+      //For UIRefreshControl to work correctly, the bounces should always be true
284
+    _webView.scrollView.bounces = _pullToRefreshEnabled || _bounces; 
281 285
     _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator;
282 286
     _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator;
283 287
     _webView.scrollView.directionalLockEnabled = _directionalLockEnabled;
@@ -308,7 +312,6 @@ static NSDictionary* customCertificatesForHost;
308 312
   _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures;
309 313
 }
310 314
 
311
-
312 315
 - (void)removeFromSuperview
313 316
 {
314 317
     if (_webView) {
@@ -1156,6 +1159,35 @@ static NSDictionary* customCertificatesForHost;
1156 1159
   }
1157 1160
 }
1158 1161
 
1162
+- (void)addPullToRefreshControl
1163
+{
1164
+    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
1165
+    _refreshControl = refreshControl;
1166
+    [_webView.scrollView addSubview: refreshControl];
1167
+    [refreshControl addTarget:self action:@selector(pullToRefresh:) forControlEvents: UIControlEventValueChanged];
1168
+}
1169
+
1170
+- (void)pullToRefresh:(UIRefreshControl *)refreshControl
1171
+{
1172
+    [self reload];
1173
+    [refreshControl endRefreshing];
1174
+}
1175
+
1176
+#if !TARGET_OS_OSX
1177
+- (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled
1178
+{
1179
+    _pullToRefreshEnabled = pullToRefreshEnabled;
1180
+    
1181
+    if (pullToRefreshEnabled) {
1182
+        [self addPullToRefreshControl];
1183
+    } else {
1184
+        [_refreshControl removeFromSuperview];
1185
+    }
1186
+
1187
+    [self setBounces:_bounces];
1188
+}
1189
+#endif // !TARGET_OS_OSX
1190
+
1159 1191
 - (void)stopLoading
1160 1192
 {
1161 1193
   [_webView stopLoading];
@@ -1165,11 +1197,11 @@ static NSDictionary* customCertificatesForHost;
1165 1197
 - (void)setBounces:(BOOL)bounces
1166 1198
 {
1167 1199
   _bounces = bounces;
1168
-  _webView.scrollView.bounces = bounces;
1200
+    //For UIRefreshControl to work correctly, the bounces should always be true
1201
+  _webView.scrollView.bounces = _pullToRefreshEnabled || bounces;
1169 1202
 }
1170 1203
 #endif // !TARGET_OS_OSX
1171 1204
 
1172
-
1173 1205
 - (void)setInjectedJavaScript:(NSString *)source {
1174 1206
   _injectedJavaScript = source;
1175 1207
 

+ 4
- 0
apple/RNCWebViewManager.m View File

@@ -103,6 +103,10 @@ RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)m
103 103
   }];
104 104
 }
105 105
 
106
+RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebView) {
107
+    view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json];
108
+}
109
+
106 110
 RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) {
107 111
   view.bounces = json == nil ? true : [RCTConvert BOOL: json];
108 112
 }

+ 11
- 0
docs/Reference.md View File

@@ -67,6 +67,7 @@ This document lays out the current public properties and methods for the React N
67 67
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
68 68
 - [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled)
69 69
 - [`textZoom`](Reference.md#textZoom)
70
+- [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled)
70 71
 - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch)
71 72
 - [`onFileDownload`](Reference.md#onFileDownload)
72 73
 
@@ -1193,6 +1194,16 @@ Example:
1193 1194
 
1194 1195
 `<WebView textZoom={100} />`
1195 1196
 
1197
+---
1198
+
1199
+### `pullToRefreshEnabled`[⬆](#props-index)<!-- Link generated with jump2header -->
1200
+
1201
+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`.
1202
+
1203
+| Type    | Required | Platform |
1204
+| ------- | -------- | -------- |
1205
+| boolean | No       | iOS      |
1206
+
1196 1207
 ### `ignoreSilentHardwareSwitch`[⬆](#props-index)<!-- Link generated with jump2header -->
1197 1208
 
1198 1209
 (ios only)

+ 10
- 1
src/WebViewTypes.ts View File

@@ -417,7 +417,7 @@ export interface IOSWebViewProps extends WebViewSharedProps {
417 417
   /**
418 418
    * Defaults to `recommended`, which loads mobile content on iPhone
419 419
    * and iPad Mini but desktop content on other iPads.
420
-   * 
420
+   *
421 421
    * Possible values are:
422 422
    * - `'recommended'`
423 423
    * - `'mobile'`
@@ -551,6 +551,15 @@ export interface IOSWebViewProps extends WebViewSharedProps {
551 551
   */
552 552
   injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean;
553 553
 
554
+  /**
555
+   * Boolean value that determines whether a pull to refresh gesture is
556
+   * available in the `WebView`. The default value is `false`.
557
+   * If `true`, sets `bounces` automatically to `true`
558
+   * @platform ios
559
+   *
560
+  */
561
+  pullToRefreshEnabled?: boolean;
562
+
554 563
   /**
555 564
    * Function that is invoked when the client needs to download a file.
556 565
    *