[Mac OS] 如何为 WebView 内含的 NSScrollView 指定一个自定义的类呢?

2012-09-10 15:17:58 +08:00
 chenluois
subclass 了一个 NSScrollView,做了一些自定义的修改,命名为 CLScrollView。
现在想把 WebView 内含的 NSScrollView 的类指定为 CLScrollView,请问要如何做到呢?

由于 WebView 比较特殊,并不能直接在 IB 里为其包含的 view 指定类。其包含的 NSScrollView 也只能通过:
(假设这个 WebView 名为 myWebView)

[[[[myWebView mainFrame] frameView] documentView] enclosingScrollView]

来访问。

有没有办法能把其下的 enclosingScrollView 的类设为 CLScrollView 呢?
5999 次点击
所在节点    iDev
22 条回复
Veelian
2012-09-10 15:54:59 +08:00
**WebView 内含的 NSScrollView** 不是这样的,WebView是继承自NSScrollView,而不是内含的NSScrollView,你可以写个WebView继承CLScrollView,实现NSWebViewDelegate方法
lldong
2012-09-10 16:26:35 +08:00
或许可以用这个运行时API
Class class_setSuperclass(Class cls, Class newSuper)
tab
2012-09-10 16:43:38 +08:00
没做过Mac开发,@Veelian 说的在iOS SDK下是正确的。但总的思路应该是继承WebView重写一个吧?
lldong
2012-09-10 17:07:45 +08:00
@Veelian 不过WebView不是继承自NSSCrollView吧,继承自NSView。 scroll view应该是在WebFrameView里面。
chenluois
2012-09-10 17:30:59 +08:00
@Veelian "写个WebView继承CLScrollView" - 这个让我头大了,可以给点儿提示吗?
jjgod
2012-09-10 18:32:14 +08:00
ghawkgu
2012-09-10 18:48:30 +08:00
关键词:isa swizzling
自己去搜吧〜
lldong
2012-09-10 19:45:42 +08:00
WebView里面的那个scrollview是个NSScrollView的子类对象,如果要体换的话应该要用WebDynamicScrollBarsView的子类对象才对。
chenluois
2012-09-11 15:55:41 +08:00
先感谢各位的回答!昨天按各位提供的思路折腾了一晚上,虽然没有成功,但至少可以慢慢试了,今天继续学习。

@Veelian 提供的思路我卡在 "写个WebView继承CLScrollView" 上了,WebView 继承自 NSView : NSResponder : NSObject,想了半天也没弄明白怎样才能 subclass 一个 WebView,并且让它继承 CLScrollView。Subclass 一个 WebView,它不只能是继承 WebView 么?

@tab 关键问题就是,subclass 了一个 WebView 后,要重写哪个函数才能把 WebView 里面的 scrollView 的类替换为 CLScrollView 呢?

@lldong @jjgod @ghawkgu 三位提供的思路,如果我没有理解错,你们说的是同一个东西,在运行时替换 NSScrollView 里面的某个方法。对运行时不了解,昨天看了几页 @lldong 分享的幻灯片,今天继续看。
http://lldong.github.com/blog/2012/03/05/objective-c-runtime/
virushuo
2012-09-11 16:07:38 +08:00
@lldong @jjgod 我一直想知道,runtime替换会导致不能上架吗?如果用runtime替换掉了一个苹果没公开的类的某个方法,这样会等同于私有api吗?(理论上虽然是一样的)。但runtime的操作很难察觉,那么用这办法调用私有api不是就很难被审核发现了吗? 你们有人试过吗?
lldong
2012-09-11 16:09:02 +08:00
@chenluois 可以直接看WebKit的源代码,这样就知道该往哪里下手了
https://svn.webkit.org/repository/webkit/trunk/Source/WebKit/mac/WebView/
jjgod
2012-09-11 16:42:11 +08:00
@virushuo: 调用私有 API 等于是用 Apple 的实现,运行时替换方法是用你自己的实现,这两者是有区别的吧。
virushuo
2012-09-11 16:45:25 +08:00
@jjgod 如果我实现了一个苹果没公开的类中的一个方法的实现呢? 苹果不让用私有api的理由不就是他们随时会改动这些,但我现在问题是找到了一个他没实现的方法。虽然实际上我这么做没危险,因为就算苹果实现了也不会干扰我。
lldong
2012-09-11 16:49:32 +08:00
@virushuo 试过method swizzling替换NavigationBar的drawRect方法,并不影响上架,但是也听过替换非私有API被查出来的,也听过因为方法名和某私有API一样被reject的,所以蛮好奇苹果的审查的方法。我觉得如果要保险的话各种方法名也要在运行时拼凑出来,甚至不要过objc_msgSend()去调用。
chenluois
2012-09-11 19:37:53 +08:00
@lldong 谢谢!我去看看
nowa
2012-09-20 23:42:15 +08:00
@chenluois 我也遇到了同样的问题,感觉如果改动比较大的话用method swizzling太繁琐了。WebDynamicScrollBarsView没有公开,也无法继承。

不知最后采取了怎样的方案?
chenluois
2012-09-21 06:02:47 +08:00
@nowa 最后,放弃了…
nowa
2012-09-21 07:24:49 +08:00
@chenluois 汗。我先一个个method exchange吧。。。
clowwindy
2012-09-21 09:43:15 +08:00
试过 method swizzling,替换过 NSURLRequest 的方法,对 WebView 做一些 header 过滤。不影响上架。
jerry
2012-09-21 09:50:15 +08:00
替换的目的是什么呢?如果是换滚动条,隐藏掉原来的,旁边再画一个

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/47365

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX