Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 不带接口生成器的自定义UITabBar子类_Ios_Swift_Uikit_Uitabbarcontroller_Uitabbar - Fatal编程技术网

Ios 不带接口生成器的自定义UITabBar子类

Ios 不带接口生成器的自定义UITabBar子类,ios,swift,uikit,uitabbarcontroller,uitabbar,Ios,Swift,Uikit,Uitabbarcontroller,Uitabbar,使用IB(无论是故事板还是XIB),通过在Identity Inspector->Custom class中编辑类名,可以很容易地让UITabBarController使用UITabBar的子类 如何模仿IB的这个“自定义类”特性,而不使用它 我尝试了以下方法(在我的UITabBarController子类中): 无效–将显示选项卡栏,但为空。问题不在其他地方,因为被覆盖的var中的returningsuper.tabBar修复了它 我想,问题是我没有设置我的customTabBar(框架、位置

使用IB(无论是故事板还是XIB),通过在Identity Inspector->Custom class中编辑类名,可以很容易地让UITabBarController使用UITabBar的子类

如何模仿IB的这个“自定义类”特性,而不使用它

我尝试了以下方法(在我的UITabBarController子类中):

无效–将显示选项卡栏,但为空。问题不在其他地方,因为被覆盖的
var
中的
return
ing
super.tabBar
修复了它

我想,问题是我没有设置我的
customTabBar
(框架、位置,将其添加到视图层次结构),但我希望让UITabBarController
loadView
(我想这是一个,不确定)为我做这件事,就像它设置任何其他
UITabBar
一样


想法

我想你不能。对于这个问题,我花了一些时间浏览了
uitabar
UITabBarController
的文档

UITabBarController
tabBar
属性仅为get属性

@available(iOS 3.0, *)
    open var tabBar: UITabBar { get } // Provided for -[UIActionSheet showFromTabBar:]. Attempting to modify the contents of the tab bar directly will throw an exception.
此外,
UITabBarController
中规定,您不应操纵此类属性

决不应试图操纵UITabBar对象本身 存储在此属性中。如果尝试执行此操作,则选项卡栏视图 抛出异常。为选项卡栏配置项目的步骤 接口,则应指定一个或多个自定义视图 将控制器添加到viewControllers属性。选项卡栏收集 指定的视图控制器中所需的选项卡栏项

此属性提供的选项卡栏视图仅适用于各种情况 要使用show(from:)方法显示操作表的位置 UIActionSheet类的

只想添加:但与此
uitabarcontroller
不同,对
UINavigationController
进行子类化可以使用
UINavigationBar
子类初始化此类子类:

UINavigationController(navigationBarClass: <#T##AnyClass?#>, toolbarClass: <#T##AnyClass?#>)
UINavigationController(导航栏类:,工具栏类:)

不幸的是,
UITabBarController
没有这种init方法。

如果你选择无视苹果关于支持什么的说法(使用自定义uitabar子类和Interface Builder,并且只使用它),这里有一个肮脏的解决方案(有效):

它需要对ObjC运行时有一点了解,因为我们将在运行时对内容进行快速转换。。。本质上,问题是我不能强制UITabBarController实例化我希望它实例化的类(这里是MyCustomTabBarSubclass)。相反,它总是实例化
uitabar

但我知道它是如何实例化的:通过调用
-[[uitabar alloc]initWithFrame:][/code>。我还知道,属于
init
系列的所有函数都可以返回其类的实例或子类的实例(这是类集群的基础)

所以,我要用这个。我将用我的自定义版本swizzle(=替换实现)uitabar的
-initWithFrame:
方法,它不会调用(
self=[super initWithFrame:
)而会调用“down”(
self=[MyCustomTabBarSubclass.alloc initWithFrame:
)。因此,返回的对象将是MyCustomTabBarSubclass类,这正是我试图实现的

注意我是如何调用
MyCustomTabBarSubclass.alloc
——这是因为我的子类可能有UITabBar没有的IVAR,从而使它在内存布局中更大。在重新分配self之前,我可能必须先释放self,否则我可能会泄漏分配的内存,但我一点也不确定(而且ARC“禁止”我调用
-release
,所以我必须使用另一个欺骗步骤来调用它)


编辑

(首先,此方法也适用于使用IB自定义类的任何情况)

还要注意,实现这一点需要编写ObjC代码,因为Swift不允许我们调用
alloc
,例如,没有双关语。代码如下:

IMP originalImp=NULL;
id uuu Swizzle_InitWithFrame(id self,SEL _cmd,CGRect frame)
{
c类=NSClassFromString(@“MyBundleName.MyCustomTabBarSubclass”);
self=[c alloc];//因此我们将返回MyCustomTabBarSubclass的一个实例
如果(自我){
id(*castedImp)(id,SEL,CGRect)=(id(*)(id,SEL,CGRect))原始IP;
self=castedImp(self,_cmd,frame);/-[super initWithFrame:]
}
回归自我;
}
您还必须确保实际的滑动操作只执行一次(例如,
dispatch\u once
)。下面是实际运行的代码:

Method=class\u getInstanceMethod(NSClassFromString(@“uitabar”),@selector(initWithFrame:);
IMP swizzleImp=(IMP)uu Swizzle_InitWithFrame;
originalImp=方法_setImplementation(方法,swizzleImp);
ObjC方面就是这样。 斯威夫特方面:

@objc类MyCustomTabbar子类:UITabBar{
lazy-var-anIvar:Int=0//显然只是一个例子
//别忘了让你所有的IVAR都是懒惰的或可选的
//因为初始化器不会像我们一样被调用
//绕过Swift运行时正常初始化机制
}
在初始化UITabBarController之前,不要忘记调用执行swizzling的ObjC代码

就这样!您欺骗了UITabBarController来实例化自己的UITabBar子类,而不是普通的。如果您使用的是纯ObjC,事情就更简单了(不必处理桥接头,我在这里没有介绍这个主题)

强制性免责声明:搞乱Objective运行时显然不是一件容易的事。确保没有更好的解决方案–IMHO,仅为了避免此类修补而使用XIB是更好的解决方案
UINavigationController(navigationBarClass: <#T##AnyClass?#>, toolbarClass: <#T##AnyClass?#>)
MyCustomTabBar *customTabBar = [[MyCustomTabBar alloc] initWithFrame:CGRectZero];
customTabBar.delegate = self;
[self setValue:customTabBar forKey:@"tabBar"];