ios 有很多私有的类和函数,令人忧伤的是这些官方都不给用,对于一个开发者来说这是相当纠结的一件事。但如果你知道这个私有方法怎么实现的话呢?完全可以自己改写这些私有类和方法,下面以改写UIVebView这个类的一些方法作为例子来说明一下。
UIWebView 了view结构大概如下:
UIWebView:
_UIWebViewScrollView(其实是scrollview)
多个UIImageView
UIWebBrowserView:
UIWebBrowserViewMinusAccessoryView
UIWebBrowserView 和 _UIWebViewScrollView都是我们不是能直接用的类,UIWebBrowserView下的UIWebBrowserViewMinusAccessoryView直接
的控制着webkit键盘的inputAccessoryView,即图中键盘上面这一栏。假设我们要去掉webkit键盘上面这一栏,自定义为我们自己的样式,应该怎么做呢?
首先要我们要在uiwebview对象中找到UIWebBrowserView的对象,直接遍历就Ok
1 /** 2 * 找到UIWebBrowserView的对象 3 */ 4 UIView *browserView = nil; 5 for (UIView *subview in [[self.subviewsobjectAtIndex:0] subviews]) { 6 if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) { 7 browserView = subview; 8 break; 9 } 10 } 11 // 拷贝 browserView 中的UIWebBrowserViewMinusAccessoryView 12 Class newClass = objc_duplicateClass(browserView, "UIWebBrowserViewMinusAccessoryView", 0); 13 14 // 编写自己的实现方法accessoryViewImp 15 IMP accessoryViewImp = [self methodForSelector:@selector(emptyInputAccessoryView)]; 16 17 // 替换系统的inputAccessoryView方法 ,@@: 是type coding ,下面会讲到 18 class_replaceMethod(newClass, @selector(inputAccessoryView), accessoryViewImp, "@@:"); 19 20 //注册类 21 objc_registerClassPair(newClass); 22 23 //重新设计browserView对象的类 24 object_setClass(browserView, newClass); 25 26 //载入自己的inputAccessoryView 27 [browserView reloadInputViews];
一个Object-c的方法实现类型IMP 至少有两个参数self 和 _cmd,如下
1 // IMP 类型的自定义方法 2 id emptyInputAccessoryView(id self , SEL _cmd /*, NSString *str 你的其它参数 */) 3 { 4 UIView *view = [[[UIView alloc] init] autorelease]; 5 //自定义你自己的view 6 return view; 7 }
class_replaceMethod方法的最后一个参数是 type encodings ,用来标识IMP函数实现的返回值与参数,其中,
第一个字段@表示返回值是id类型
第二个字段@表示self参数
第三个字段:表示_cmd参数
第四个字段开始为用户定义的参数类型对应的encodings。
具体的type encodings 可以参考apple官方提供的 type encodings 对应表:
Code | Meaning |
---|---|
| A |
| An |
| A |
| A
|
| A |
| An |
| An |
| An |
| An |
| An |
| A |
| A |
| A C++ |
| A |
| A character string ( |
| An object (whether statically typed or typed |
| A class object ( |
| A method selector ( |
[array type] | An array |
{name=type...} | A structure |
(name=type...) | A union |
| A bit field of num bits |
| A pointer to type |
| An unknown type (among other things, this code is used for function pointers) |