_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的设计可以借鉴到别处,是代理模式的应用吧。