cocoa - 在 Mac OS X Lion 的 WebView 中禁用滚动动画?

标签 cocoa animation webview scroll osx-lion

如何禁用在 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/

相关文章:

Google Play 拒绝 Android 应用

objective-c - 如何在cocoa(Interface Builder)中绑定(bind)CGSize.width?

带有 Xcode.app Terminal.app 等选项卡的 Cocoa 应用程序

cocoa - 当启用多选时,NSCollectionView 在拖动之前出现烦人的延迟

android - TextView 文本大小的动画

javascript - SVG 动画线条不稳定的行为

android - 如何修复 webview_flutter 中的白屏?

objective-c - 系统偏好设置面板(安装)

javascript:如何按顺序显示 gif,避免预加载

php - 如何知道是否有人将我的网站嵌入到 Android 应用程序中?