_UIWebViewScrollView的继承链为:_UIWebViewScrollView->UIWebScrollView->UIScrollView。
通过反编译可以得到实现。_UIWebViewScrollView和UIWebScrollView的实现为:(代码好长,点此跳过)
- @interface UIWebScrollView : UIScrollView
- - (void)didMoveToWindow;
- - (BOOL)touchesShouldCancelInContentView:(id)arg1;
- @end
- @implementation UIWebScrollView
- - (void)didMoveToWindow
- {
- [super didMoveToWindow];
- if (!self.window)
- {
- SEL sel = @selector(scrollViewWasRemoved:);
- if ([super.delegate respondsToSelector:sel])
- objc_msgSend(super.delegate, sel, self);
- }
- }
- - (BOOL)touchesShouldCancelInContentView:(id)arg1
- {
- return YES;
- }
- @end
- @interface _UIWebViewScrollView : UIWebScrollView
- {
- _UIWebViewScrollViewDelegateForwarder *_forwarder;
- BOOL _bouncesSetExplicitly;
- UIWebBrowserView *_browserView;
- }
- - (void)_setWebView:(id)arg1;
- - (id)delegate;
- - (void)setDelegate:(id)arg1;
- - (void)setBouncesHorizontally:(BOOL)arg1;
- - (void)setBouncesVertically:(BOOL)arg1;
- - (void)setBounces:(BOOL)arg1;
- - (void)_weaklySetBouncesHorizontally:(BOOL)arg1;
- - (void)dealloc;
- - (id)initWithFrame:(struct CGRect)arg1;
- @end
- @implementation _UIWebViewScrollView
- - (void)_setWebView:(id)arg1
- {
- [_forwarder setWebView:arg1];
- super.delegate = nil;
- super.delegate = _forwarder;
- }
- - (id)delegate
- {
- return _forwarder.delegate;
- }
- - (void)setDelegate:(id)arg1
- {
- _forwarder.delegate = arg1;
- super.delegate = nil;
- super.delegate = _forwarder;
- }
- - (void)setBouncesHorizontally:(BOOL)arg1
- {
- [super setBouncesHorizontally:arg1];
- _bouncesSetExplicitly = YES;
- }
- - (void)setBouncesVertically:(BOOL)arg1
- {
- [super setBouncesVertically:arg1];
- _bouncesSetExplicitly = YES;
- }
- - (void)setBounces:(BOOL)arg1
- {
- [super setBounces:arg1];
- _bouncesSetExplicitly = YES;
- }
- - (void)_weaklySetBouncesHorizontally:(BOOL)arg1
- {
- if (!_bouncesSetExplicitly)
- [super setBouncesHorizontally:arg1];
- }
- - (void)dealloc
- {
- [_forwarder release];
- _forwarder = nil;
- [super dealloc];
- }
- - (id)initWithFrame:(struct CGRect)arg1
- {
- self = [super initWithFrame:arg1];
- if (self)
- {
- _forwarder = [[_UIWebViewScrollViewDelegateForwarder alloc] init];
- }
- return self;
- }
- @end
UIWebScrollView比UIScrollView多做了两件事:
- 永远对contentView cancel touch
- 通知delegate自己被移出window的view hierarchy
_UIWebViewScrollView比UIWebScrollView多做了一件事:记录是否被显式设置了Bounces属性。
(UIWebScrollView有其它子类)
_UIWebViewScrollViewDelegateForwarder的实现如下:(代码好长,点此跳过)
- @interface _UIWebViewScrollViewDelegateForwarder : NSObject <UIScrollViewDelegate>
- {
- id <UIScrollViewDelegate> _delegate;
- UIWebView *_webView;
- }
- @property(nonatomic) UIWebView *webView; // @synthesize webView=_webView;
- @property(nonatomic) id <UIScrollViewDelegate> delegate; // @synthesize delegate=_delegate;
- - (void)forwardInvocation:(id)arg1;
- - (BOOL)respondsToSelector:(SEL)arg1;
- - (id)methodSignatureForSelector:(SEL)arg1;
- @end
- @implementation _UIWebViewScrollViewDelegateForwarder
- @synthesize webView=_webView;
- @synthesize delegate=_delegate;
- - (void)forwardInvocation:(NSInvocation*)arg1
- {
- SEL sel = [arg1 selector];
- bool hasWebViewResponded = false;
- if ([_webView respondsToSelector:sel])
- {
- [arg1 invokeWithTarget:_webView];
- hasWebViewResponded = true;
- }
- if([_delegate respondsToSelector:sel])
- {
- [arg1 invokeWithTarget:_delegate];
- }
- else
- {
- if (!hasWebViewResponded)
- {
- [super forwardInvocation:arg1];
- }
- }
- }
- - (BOOL)respondsToSelector:(SEL)arg1
- {
- bool result = [super respondsToSelector:arg1];
- if (!result)
- {
- result = [_webView respondsToSelector:arg1];
- if (!result)
- {
- result = [_delegate respondsToSelector:arg1];
- }
- }
- return result;
- }
- - (id)methodSignatureForSelector:(SEL)arg1
- {
- id result = [super methodSignatureForSelector:arg1];
- if (!result)
- {
- result = [_webView methodSignatureForSelector:arg1];
- if (!result)
- {
- result = [(NSObject*)_delegate methodSignatureForSelector:arg1];
- }
- }
- return result;
- }
- @end
_UIWebViewScrollViewDelegateForwarder所做的就是把传向_UIWebViewScrollView的消息转发给delegate。这个forwarder的设计可以借鉴到别处,是代理模式的应用吧。