检测以编程方式设置的 UITabBar 选定索引/项目更改
Detect UITabBar Selected Index/ Item Changes that is set Programmatically
我想知道我们如何检测选定的 TabBar 项或索引何时更改何时 更改以编程方式完成?
self.tabBarController.selectedIndex = 1;
这两个委托函数仅在用户选择 tabBar Item 时检测更改。当以编程方式完成对 selectedIndex 的更改时,它不会触发。
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
println("tabBarController didSelectViewController")
}
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
println("tabBar didSelectItem")
}
我找到了一个很好的解决方案。感谢 Ckouta 的想法。
我只是创建了一个函数来更改索引并触发 UITabBar 的 didSelectItem 的委托协议
func selectItemWithIndex(value: Int) {
self.tabBarControllertabBarController.selectedIndex = value;
self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
用法
selectItemWithIndex(1);
以前的答案足以 "detect" 更改,但是它没有检测到正在按下哪个索引。
func selectItemWithIndex(value: Int) {
self.tabBarControllertabBarController.selectedIndex = value;
self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
self.selectedIndex 不会立即 return 选择的索引。要检查哪个项目被按下,我们需要将该项目与 UITabBarController
中的 tabBarItems 进行比较
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
if item == (self.tabBar.items as! [UITabBarItem])[0]{
//Do something if index is 0
}
else if item == (self.tabBar.items as! [UITabBarItem])[1]{
//Do something if index is 1
}
}
这无法完成,但可以进行某种破解,我相信这将是解决此问题的临时解决方案。
覆盖下面的 tabbarcontrollerdelegate 方法,在里面做你的东西当以编程方式切换选项卡或点击选项卡栏项目时调用此方法。
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
toVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaMedium11, NSForegroundColorAttributeName: UIColor.colorAppThemeColor], for: .normal)
fromVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaBTBook11, NSForegroundColorAttributeName: UIColor.colorStudentTabText], for: .normal)
return nil
}
我只关心选项卡栏控制器堆栈中 VC 之一的 selectedIndex。所以我 KVO:ed segmentedIndex 来自 VC 的 tabbarcontroller 实例。运行良好,没有实际问题。
Swift 3
这里有一个更安全的 Swift-3 版本,上面提出的是:
func selectItem(withIndex index: Int) {
if let controller = tabBarController,
let tabBar = tabBarController?.tabBar,
let items = tabBarController?.tabBar.items
{
guard index < items.count else { return }
controller.selectedIndex = index
controller.tabBar(tabBar, didSelect: items[index])
}
}
UITabBarController:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if let items = tabBar.items {
items.enumerated().forEach { if == item { print("your index is: \([=11=])") } }
}
}
用法:
selectItem(withIndex: 1)
在 swift 中,您可以覆盖 UITabBarController
的 selectedIndex
属性。
首先子类 UITabBarController
并添加以下所有代码。
//Overriding this to get callback whenever its value is changes
override var selectedIndex: Int {
didSet {
handleTabSelection(selectedIndex: selectedIndex)
}
}
同时添加UITabBarControllerDelegate
的委托方法
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
//Tab tapped
guard let viewControllers = tabBarController.viewControllers else { return }
let tappedIndex = viewControllers.index(of: viewController)!
//Tab tapped at tappedIndex
handleTabSelection(selectedIndex: tappedIndex)
}
最后,我们从两个地方调用此方法,以便处理所有情况。
private func handleTabSelection(selectedIndex: Int) {
//Do something on tab selection at selectedIndex
}
对于此处的所有答案,如果您已经对 UITabBarController
进行了子类化,那么这里有一个针对所有选项卡栏更改(用户启动和程序化)的简单解决方案:
// Override selectedViewController for User initiated changes
override var selectedViewController: UIViewController? {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// Override selectedIndex for Programmatic changes
override var selectedIndex: Int {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// handle new selection
func tabChangedTo(selectedIndex: Int) {}
Swift 4:- 您必须使用这些代码行来检测 UITabBar
所选项目索引。
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item == (tabBar.items)![0] {
// do something with 1st tab
}
else if item == (tabBar.items)![1] {
// do something with 2nd tab
}
}
我想知道我们如何检测选定的 TabBar 项或索引何时更改何时 更改以编程方式完成?
self.tabBarController.selectedIndex = 1;
这两个委托函数仅在用户选择 tabBar Item 时检测更改。当以编程方式完成对 selectedIndex 的更改时,它不会触发。
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
println("tabBarController didSelectViewController")
}
override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
println("tabBar didSelectItem")
}
我找到了一个很好的解决方案。感谢 Ckouta 的想法。
我只是创建了一个函数来更改索引并触发 UITabBar 的 didSelectItem 的委托协议
func selectItemWithIndex(value: Int) {
self.tabBarControllertabBarController.selectedIndex = value;
self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
用法
selectItemWithIndex(1);
以前的答案足以 "detect" 更改,但是它没有检测到正在按下哪个索引。
func selectItemWithIndex(value: Int) {
self.tabBarControllertabBarController.selectedIndex = value;
self.tabBar(self.tabBar, didSelectItem: (self.tabBar.items as! [UITabBarItem])[value]);
}
self.selectedIndex 不会立即 return 选择的索引。要检查哪个项目被按下,我们需要将该项目与 UITabBarController
中的 tabBarItems 进行比较override func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
if item == (self.tabBar.items as! [UITabBarItem])[0]{
//Do something if index is 0
}
else if item == (self.tabBar.items as! [UITabBarItem])[1]{
//Do something if index is 1
}
}
这无法完成,但可以进行某种破解,我相信这将是解决此问题的临时解决方案。 覆盖下面的 tabbarcontrollerdelegate 方法,在里面做你的东西当以编程方式切换选项卡或点击选项卡栏项目时调用此方法。
func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
{
toVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaMedium11, NSForegroundColorAttributeName: UIColor.colorAppThemeColor], for: .normal)
fromVC.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.fontFuturaBTBook11, NSForegroundColorAttributeName: UIColor.colorStudentTabText], for: .normal)
return nil
}
我只关心选项卡栏控制器堆栈中 VC 之一的 selectedIndex。所以我 KVO:ed segmentedIndex 来自 VC 的 tabbarcontroller 实例。运行良好,没有实际问题。
Swift 3
这里有一个更安全的 Swift-3 版本,上面提出的是:
func selectItem(withIndex index: Int) {
if let controller = tabBarController,
let tabBar = tabBarController?.tabBar,
let items = tabBarController?.tabBar.items
{
guard index < items.count else { return }
controller.selectedIndex = index
controller.tabBar(tabBar, didSelect: items[index])
}
}
UITabBarController:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if let items = tabBar.items {
items.enumerated().forEach { if == item { print("your index is: \([=11=])") } }
}
}
用法:
selectItem(withIndex: 1)
在 swift 中,您可以覆盖 UITabBarController
的 selectedIndex
属性。
首先子类 UITabBarController
并添加以下所有代码。
//Overriding this to get callback whenever its value is changes
override var selectedIndex: Int {
didSet {
handleTabSelection(selectedIndex: selectedIndex)
}
}
同时添加UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
//Tab tapped
guard let viewControllers = tabBarController.viewControllers else { return }
let tappedIndex = viewControllers.index(of: viewController)!
//Tab tapped at tappedIndex
handleTabSelection(selectedIndex: tappedIndex)
}
最后,我们从两个地方调用此方法,以便处理所有情况。
private func handleTabSelection(selectedIndex: Int) {
//Do something on tab selection at selectedIndex
}
对于此处的所有答案,如果您已经对 UITabBarController
进行了子类化,那么这里有一个针对所有选项卡栏更改(用户启动和程序化)的简单解决方案:
// Override selectedViewController for User initiated changes
override var selectedViewController: UIViewController? {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// Override selectedIndex for Programmatic changes
override var selectedIndex: Int {
didSet {
tabChangedTo(selectedIndex: selectedIndex)
}
}
// handle new selection
func tabChangedTo(selectedIndex: Int) {}
Swift 4:- 您必须使用这些代码行来检测 UITabBar
所选项目索引。
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item == (tabBar.items)![0] {
// do something with 1st tab
}
else if item == (tabBar.items)![1] {
// do something with 2nd tab
}
}