如何禁用在 Mac OS X Lion 中使用箭头键在 WebView 中导航时出现的动画?
我尝试更改的行为似乎是 Mac OS X Lion 上 WebView 的默认行为。如果将文档加载到 WebView 中,设置插入点,然后使用向上箭头和向下箭头键进行导航,则滚动不是瞬时的 - 存在动画( View 明显向上或向下滚动)。
这是一个 Xcode 项目,您可以使用它来查看此行为(只需运行应用程序,在文档中设置插入点,然后使用向上箭头和向下箭头键进行导航,以便 View 滚动): http://dl.dropbox.com/u/78928597/WebViewTest.zip
我想要实现的行为就是 Safari 中发生的情况。如果您在 Safari 中打开 contenteditable
属性设置为 true
的 html 文档,则可以在文档内设置插入点,然后使用向上箭头和向下箭头进行导航方向键。当您以这种方式导航时,滚动不会有动画效果。 View 立即滚动。
这是一个 html 文档,您可以使用它来查看此行为: http://dl.dropbox.com/u/78928597/WebViewTest.html
由于 Safari 使用 WebView,并且它会即时滚动,因此似乎应该有一种方法可以更改任何 WebView 的滚动行为,但我没有找到它。
请注意,您需要在使用箭头键导航之前设置插入点,否则您会看到不同的行为。
最佳答案
我认为有一种方法可以做到这一点,但它需要使用 Objective-C 运行时来修改私有(private)类的私有(private)方法。
要使用 Objective-C 运行时,请添加
#import <objc/runtime.h>
到 Xcode 项目中 AppDelegate.m 顶部的 #import
指令。
滚动动画似乎发生在私有(private)方法中
- (BOOL)_scrollTo:(const CGPoint *)pointRef animate:(NSInteger)animationSpecifier flashScrollerKnobs:(NSUInteger)knobFlashSpecifier
NSClipView
。
我们无法通过子类化来修改由 WebView
管理的 NSClipView
对象(实际上是私有(private)类 WebClipView
的实例)。相反,我们可以使用一种称为“方法调配”的技术。
在 AppDelegate
类的 @implementation
中,添加
static BOOL (*kOriginalScrollTo)(id, SEL, const CGPoint *, NSInteger, NSUInteger);
static BOOL scrollTo_override(id self, SEL _cmd, const CGPoint *pointRef, NSInteger animationSpecifier, NSUInteger knobFlashSpecifier)
{
return kOriginalScrollTo(self, _cmd, pointRef, 2, knobFlashSpecifier);
}
+ (void)load
{
SEL selector = @selector(_scrollTo:animateScroll:flashScrollerKnobs:);
id WebClipViewClass = objc_getClass("WebClipView");
Method originalMethod = class_getInstanceMethod(WebClipViewClass, selector);
kOriginalScrollTo = (void *)method_getImplementation(originalMethod);
if(!class_addMethod(WebClipViewClass, selector, (IMP)scrollTo_override, method_getTypeEncoding(originalMethod))) {
method_setImplementation(originalMethod, (IMP)scrollTo_override);
}
}
您可以在 Mike Ash 的文章 “Method Replacement for Fun and Profit” 中了解有关此处发生的情况的更多信息。 ;我正在使用“直接覆盖”方法调配。
由于此代码,将调用 scrollTo_override()
而不是 WebClipView
方法 -[_scrollTo:animateScroll:flashScrollerKnobs:]
。 scrollTo_override()
所做的只是调用原始 -[_scrollTo:animateScroll:flashScrollerKnobs:]
,其中 2 作为 animationSpecifier
。这似乎可以防止滚动动画发生。
关于cocoa - 在 Mac OS X Lion 的 WebView 中禁用滚动动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10558942/