Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(714)

Side by Side Diff: ios/web/web_state/crw_web_view_scroll_view_proxy.mm

Issue 2594793004: Revert 'Bypass UIWebView.scrollView's contentInset implementation with UIScrollView's. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h" 5 #import "ios/web/public/web_state/crw_web_view_scroll_view_proxy.h"
6 6
7 #import <objc/runtime.h> 7 #import <objc/runtime.h>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #import "base/ios/crb_protocol_observers.h" 10 #import "base/ios/crb_protocol_observers.h"
11 #include "base/mac/foundation_util.h" 11 #include "base/mac/foundation_util.h"
12 #import "base/mac/scoped_nsobject.h" 12 #import "base/mac/scoped_nsobject.h"
13 13
14 #if !defined(__has_feature) || !__has_feature(objc_arc) 14 #if !defined(__has_feature) || !__has_feature(objc_arc)
15 #error "This file requires ARC support." 15 #error "This file requires ARC support."
16 #endif 16 #endif
17 17
18 @interface CRWWebViewScrollViewProxy () { 18 @interface CRWWebViewScrollViewProxy () {
19 __weak UIScrollView* _scrollView; 19 __weak UIScrollView* _scrollView;
20 base::scoped_nsobject<id> _observers; 20 base::scoped_nsobject<id> _observers;
21 // When |_ignoreScroll| is set to YES, do not pass on -scrollViewDidScroll
22 // calls to observers. This is used by -setContentInsetFast, which needs to
23 // update and reset the contentOffset to force a fast update. These updates
24 // should be a no-op for the contentOffset, so the callbacks can be ignored.
25 BOOL _ignoreScroll;
26 } 21 }
27 22
28 // Returns the key paths that need to be observed for UIScrollView. 23 // Returns the key paths that need to be observed for UIScrollView.
29 + (NSArray*)scrollViewObserverKeyPaths; 24 + (NSArray*)scrollViewObserverKeyPaths;
30 25
31 // Adds and removes |self| as an observer for |scrollView| with key paths 26 // Adds and removes |self| as an observer for |scrollView| with key paths
32 // returned by |+scrollViewObserverKeyPaths|. 27 // returned by |+scrollViewObserverKeyPaths|.
33 - (void)startObservingScrollView:(UIScrollView*)scrollView; 28 - (void)startObservingScrollView:(UIScrollView*)scrollView;
34 - (void)stopObservingScrollView:(UIScrollView*)scrollView; 29 - (void)stopObservingScrollView:(UIScrollView*)scrollView;
35 30
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 102 }
108 103
109 - (void)setContentOffset:(CGPoint)contentOffset { 104 - (void)setContentOffset:(CGPoint)contentOffset {
110 [_scrollView setContentOffset:contentOffset]; 105 [_scrollView setContentOffset:contentOffset];
111 } 106 }
112 107
113 - (CGPoint)contentOffset { 108 - (CGPoint)contentOffset {
114 return _scrollView ? [_scrollView contentOffset] : CGPointZero; 109 return _scrollView ? [_scrollView contentOffset] : CGPointZero;
115 } 110 }
116 111
117 - (void)setContentInsetFast:(UIEdgeInsets)contentInset {
118 if (!_scrollView)
119 return;
120
121 // The method -scrollViewSetContentInsetImpl below is bypassing UIWebView's
122 // subclassed UIScrollView implemention of setContentOffset. UIKIt's
123 // implementation calls the internal method |_updateViewSettings| after
124 // updating the contentInsets. This ensures things like absolute positions
125 // are correctly updated. The problem is |_updateViewSettings| does lots of
126 // other things and is very very slow. The workaround below simply sets the
127 // scrollView's content insets directly, and then fiddles with the
128 // contentOffset below to correct the absolute positioning of elements.
129 static void (*scrollViewSetContentInsetImpl)(id, SEL, UIEdgeInsets);
130 static SEL setContentInset;
131 static dispatch_once_t onceToken;
132 dispatch_once(&onceToken, ^{
133 setContentInset = @selector(setContentInset:);
134 scrollViewSetContentInsetImpl =
135 (void (*)(id, SEL, UIEdgeInsets))class_getMethodImplementation(
136 [UIScrollView class], setContentInset);
137 });
138 scrollViewSetContentInsetImpl(_scrollView, setContentInset, contentInset);
139
140 // Change and then reset the contentOffset to force the view into updating the
141 // absolute position of elements and content frame. Updating the
142 // contentOffset will cause the -scrollViewDidScroll callback to fire.
143 // Because we are eventually setting the contentOffset back to it's original
144 // position, we can ignore these calls.
145 base::AutoReset<BOOL> autoReset(&_ignoreScroll, YES);
146 CGPoint contentOffset = [_scrollView contentOffset];
147 _scrollView.contentOffset = CGPointMake(contentOffset.x, contentOffset.y + 1);
148 _scrollView.contentOffset = contentOffset;
149 }
150
151 - (void)setContentInset:(UIEdgeInsets)contentInset { 112 - (void)setContentInset:(UIEdgeInsets)contentInset {
152 [_scrollView setContentInset:contentInset]; 113 [_scrollView setContentInset:contentInset];
153 } 114 }
154 115
155 - (UIEdgeInsets)contentInset { 116 - (UIEdgeInsets)contentInset {
156 return _scrollView ? [_scrollView contentInset] : UIEdgeInsetsZero; 117 return _scrollView ? [_scrollView contentInset] : UIEdgeInsetsZero;
157 } 118 }
158 119
159 - (void)setScrollIndicatorInsets:(UIEdgeInsets)scrollIndicatorInsets { 120 - (void)setScrollIndicatorInsets:(UIEdgeInsets)scrollIndicatorInsets {
160 [_scrollView setScrollIndicatorInsets:scrollIndicatorInsets]; 121 [_scrollView setScrollIndicatorInsets:scrollIndicatorInsets];
(...skipping 21 matching lines...) Expand all
182 143
183 - (NSArray*)gestureRecognizers { 144 - (NSArray*)gestureRecognizers {
184 return [_scrollView gestureRecognizers]; 145 return [_scrollView gestureRecognizers];
185 } 146 }
186 147
187 #pragma mark - 148 #pragma mark -
188 #pragma mark UIScrollViewDelegate callbacks 149 #pragma mark UIScrollViewDelegate callbacks
189 150
190 - (void)scrollViewDidScroll:(UIScrollView*)scrollView { 151 - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
191 DCHECK_EQ(_scrollView, scrollView); 152 DCHECK_EQ(_scrollView, scrollView);
192 if (!_ignoreScroll) { 153 [_observers webViewScrollViewDidScroll:self];
193 [_observers webViewScrollViewDidScroll:self];
194 }
195 } 154 }
196 155
197 - (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView { 156 - (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView {
198 DCHECK_EQ(_scrollView, scrollView); 157 DCHECK_EQ(_scrollView, scrollView);
199 [_observers webViewScrollViewWillBeginDragging:self]; 158 [_observers webViewScrollViewWillBeginDragging:self];
200 159
201 // TODO(crbug.com/555723) Remove this once the fix to 160 // TODO(crbug.com/555723) Remove this once the fix to
202 // https://bugs.webkit.org/show_bug.cgi?id=148086 makes it's way in to iOS. 161 // https://bugs.webkit.org/show_bug.cgi?id=148086 makes it's way in to iOS.
203 scrollView.decelerationRate = UIScrollViewDecelerationRateNormal; 162 scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
204 } 163 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 - (void)observeValueForKeyPath:(NSString*)keyPath 224 - (void)observeValueForKeyPath:(NSString*)keyPath
266 ofObject:(id)object 225 ofObject:(id)object
267 change:(NSDictionary*)change 226 change:(NSDictionary*)change
268 context:(void*)context { 227 context:(void*)context {
269 DCHECK_EQ(object, _scrollView); 228 DCHECK_EQ(object, _scrollView);
270 if ([keyPath isEqualToString:@"contentSize"]) 229 if ([keyPath isEqualToString:@"contentSize"])
271 [_observers webViewScrollViewDidResetContentSize:self]; 230 [_observers webViewScrollViewDidResetContentSize:self];
272 } 231 }
273 232
274 @end 233 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698