【问题标题】:How do I create a UITabBarController with a custom UITabBar class without using IB?如何在不使用 IB 的情况下创建具有自定义 UITabBar 类的 UITabBarController?
【发布时间】:2013-08-16 03:33:56
【问题描述】:
我可以使用initWithNavigationBarClass:toolbarClass: 创建带有自定义栏类的UINavigationController。 UITabBarController 似乎没有等价物,那么如何让它使用自定义的 UITabBar 类?
到目前为止我看到的每个解决方案都不合适,因为
- 它使用 IB
- 它将第二个标签栏添加到
UITabBarController,而不是更改其现有标签栏,或者
- 它会抛出
UITabBarController 并创建一个新的控制器类。
我想要在代码中创建一个真正的UITabBarController,并为其标签栏使用自定义类。我如何做到这一点?
【问题讨论】:
标签:
ios
uitabbarcontroller
【解决方案1】:
这太难了!我想出的最好方法是继承 UITabBarController,然后在 init 中执行此操作:
super.init(nibName: nil, bundle: nil)
object_setClass(self.tabBar, CustomTabBar.self)
(self.tabBar as? CustomTabBar)?.setup()
不幸的是,您不能在调用 super.init 之前设置类(无论如何都不是在 Swift 中),因此当您更改类时,init 方法已经运行,因此不会被调用在您的自定义子类上。为了解决这个问题,我刚刚添加了一个 setup() 方法来完成我的所有自定义。
Swift 中的另一个选项是扩展 UITabBar 并执行以下操作:
extension UITabBar {
open override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
/// Customise in here.
}
// Modify the height.
open override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: size.width, height: 64.0)
}
}
但是这会影响UITabBar 的所有实例,所以我更喜欢第一个选项。
【解决方案2】:
ESTabBarControlller 的这个解决方案,用于替换没有 IB 的原生 UITabBar。
open override func viewDidLoad() {
super.viewDidLoad()
let tabBar = { () -> CustomTabBar in
let tabBar = CustomTabBar()
tabBar.delegate = self
return tabBar
}()
self.setValue(tabBar, forKey: "tabBar")
}
【解决方案3】:
我认为这是不可能的。
这里是讨论UITabBarController 的tabBar 属性的Apple 文档。
你不应该尝试操纵 UITabBar 对象本身
存储在此属性中。如果您尝试这样做,标签栏视图
抛出异常。为标签栏配置项目
界面,您应该分配一个或多个自定义视图
控制器到 viewControllers 属性。标签栏收集
您指定的视图控制器中所需的标签栏项目。
此属性提供的标签栏视图仅适用于情况
您要使用 showFromTabBar 显示操作表的位置:
UIActionSheet 类的方法。
【解决方案4】:
据我所知,你不能这样做。在没有 IB 的情况下执行此操作的最佳选择是拥有自己的 UIViewController(不是 UITabBarController 的子类),然后将您自己的 UITabBar 子类添加到该控制器。
如果您决定采用这种方法,您可能还需要查看控制器层次结构。