2012-05-11 64 views
1

如何禁用在Mac OS X Lion中使用箭頭鍵在WebView內導航時發生的動畫?在Mac OS X Lion的WebView中禁用滾動動畫?

我試圖改變的行爲似乎是Mac OS X Lion上WebView的默認行爲。如果您將文檔加載到WebView中,請設置插入點,然後使用向上箭頭和向下箭頭鍵進行導航,滾動不是即時的 - 有一個動畫(該視圖明顯向上或向下滾動)。

這裏是你可以用它來查看此行爲的Xcode項目(只是運行應用程序,設置文檔中插入點,然後使用向上和向下箭頭鍵導航這樣的觀點滾動): http://dl.dropbox.com/u/78928597/WebViewTest.zip

我試圖實現的行爲是在Safari中發生的。如果您在Safari中打開一個contenteditable屬性設置爲true的html文檔,則可以在文檔中設置插入點,然後使用向上箭頭和向下箭頭鍵進行導航。以這種方式導航時,滾動不是動畫。該視圖即時滾動。

這裏是一個HTML文件,你可以用它來查看此行爲: http://dl.dropbox.com/u/78928597/WebViewTest.html

由於Safari瀏覽器使用的WebView,並立即滾動,好像應該有改變任何的WebView的滾動行爲方式,但我沒有找到它的運氣。

請注意,您需要在使用箭頭鍵導航之前設置插入點,否則您將看到不同的行爲。

+0

你想要特別爲文本區域,或一般? –

+0

我想禁用在WebView中使用向上箭頭和向下箭頭鍵進行導航時發生的動畫滾動,而不是可能出現在WebView中的textarea元素。 (WebViewTest應用程序中的WebView和WebViewTest.html文檔都不包含textarea元素。) – bsw111

+0

啊,我誤解了你想要的東西。恐怕沒有答案,但我可以指出,Safari不再使用常規的「WebView」,因爲每個選項卡實際上都在其自己的進程中運行,並且顯示爲它是主機的一部分應用 –

回答

4

我認爲有辦法做到這一點,但它需要使用Objective-C運行時修改私有類的私有方法。

要使用Objective-C運行時,在AppDelegate.m的Xcode項目頂部添加

#import <objc/runtime.h> 

#import指令。

滾動動畫出現在私有方法

- (BOOL)_scrollTo:(const CGPoint *)pointRef animate:(NSInteger)animationSpecifier flashScrollerKnobs:(NSUInteger)knobFlashSpecifier 
NSClipView

發生。

我們不能通過子類修改由WebView管理的NSClipView對象(實際上是私有類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); 
    } 
} 

你可以閱讀更多關於這裏發生了什麼邁克·阿什的文章,「Method Replacement for Fun and Profit」;我正在使用「直接覆蓋」方法調整。

由於此代碼,將調用scrollTo_override()而不是WebClipView方法-[_scrollTo:animateScroll:flashScrollerKnobs:]。所有scrollTo_override()確實是調用原始-[_scrollTo:animateScroll:flashScrollerKnobs:]與2作爲animationSpecifier。這似乎阻止了滾動動畫的發生。