选中选项卡时弹出到根视图

时间:2011-10-04 15:57:23

标签: iphone ios uinavigationcontroller uitabbarcontroller

我遇到了一些我认为可能很容易的问题。我在根视图控制器中有一个表,当选择一行时,我按下一个新视图,然后从那里转到另一个选项卡。

我的问题是如何确保用户点击第一个标签后导航控制器会弹出到root?

14 个答案:

答案 0 :(得分:26)

在tabbar上选择每个选项卡时调用以下委托。

-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController

将以下代码放在此委托方法中。

if ([viewController isKindOfClass:[UINavigationController class]]) 
    {
        [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
    }

它在我的应用上工作正常。

答案 1 :(得分:10)

对于斯威夫特爱好者:

delay_stub = double
expect(delay_stub).to receive(:create).with(...).and_return(...)
expect(Event).to receive(:delay).with(...).and_return(delay_stub)

编辑: Swift 3更新,感谢@Justin Oroz指出这一点。

答案 2 :(得分:4)

在Swift 3.1中

将UITabBarControllerDelegate添加到TabBar类:

  类YourClass:UITabBarController,UITabBarControllerDelegate {

后:

  

覆盖func tabBar(tabBar:UITabBar,didSelectItem项目:   UITabBarItem){

let yourView = self.viewControllers![self.selectedIndex] as! UINavigationController
yourView .popToRootViewControllerAnimated(false) 
     

}

答案 3 :(得分:3)

你想要做的事听起来有点奇怪。您是否阅读过关于组合UINavigationControllers和UITabBarControllers的人机界面指南?

但是,您需要做的是通过为UITabBarController设置委托并实现tabBarController:didSelectViewController:委托方法来检测选项卡的选择。在此方法中,您需要使用UINavigationController的popToRootViewControllerAnimated:方法回弹到根视图控制器。

答案 4 :(得分:2)

[self.navigationController popToRootViewControllerAnimated:NO];

答案 5 :(得分:1)

尝试一下。

class TabBarClass: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        let vc = self.viewControllers![selectedIndex] as! UINavigationController
        vc.popToRootViewController(animated: false)
    }
}

答案 6 :(得分:1)

Swift 5.1答案:

  class YourTabBarName: UITabBarController, UITabBarControllerDelegate
    {

     override func viewDidLoad()
        {
            super.viewDidLoad()
            self.delegate = self
        }


     func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
        {
            if let vc = viewController as? UINavigationController
            { vc.popToRootViewController(animated: false) }
        }
    }

答案 7 :(得分:0)

首先,您应该创建UITabbarController的子类并添加Observer:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tabBar addObserver:self forKeyPath:@"selectedItem" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}

选择标签栏后,我们将按方法处理:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"selectedItem"] && [object isKindOfClass:[UITabBar class]]){
        UITabBar *bar = (UITabBar *)object; // The object will be the bar we're observing.
        // The change dictionary will contain the previous tabBarItem for the "old" key.
        UITabBarItem *wasItem = [change objectForKey:NSKeyValueChangeOldKey];
        NSUInteger was = [bar.items indexOfObject:wasItem];
        // The same is true for the new tabBarItem but it will be under the "new" key.
        UITabBarItem *isItem = [change objectForKey:NSKeyValueChangeNewKey];
        NSUInteger is = [bar.items indexOfObject:isItem];
        if (is == was) {
           UIViewController *vc = self.viewControllers[is];
            if ([vc isKindOfClass:[UINavigationController class]]) {
                [(UINavigationController *)vc popToRootViewControllerAnimated:YES];
            }
        }
    }
}

答案 8 :(得分:0)

UTabController建议使用不同的UX来让用户“弹出root”。切换回选项卡时,它会保留之前的完整UINav堆栈。如果他们再次点击条形项(点击选定的标签),则只会弹出到根。这都是自动的。某些应用程序(如Instagram)允许第三次点击滚动到顶部。

我建议坚持使用默认值,因为这是用户期望的。

答案 9 :(得分:0)

下面的内容对我有用。这个代码在swift 3:

1>子类UITabbarController并使用一个iVAr实现以下两个方法:
    class MyTabBarController: UITabBarController ,UITabBarControllerDelegate { var previousSelectedTabIndex : Int = -1 }

2 - ;在viewdidLoad中设置tabbar委托

override func viewDidLoad() {    
    super.viewDidLoad()
    self.delegate = self    // you must do it}  

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {

    self.previousSelectedTabIndex = tabBarController.selectedIndex
}     
func tabBarController(_ tabBarController: UITabBarController,
                               shouldSelect viewController: UIViewController) -> Bool {    

    if  self.previousSelectedTabIndex == tabBarController.selectedIndex {
        let   nav  =  viewController as! UINavigationController // mine in nav_VC
        for vc in nav.childViewControllers {
            if vc is YUOR_DESIRED_VIEW_CONTROLLER {
            nav.popToViewController(vc, animated: true)
            return false// IT WONT LET YOU GO TO delegate METHOD
            }
        }
    }
 return true
}    

tabBarController.selectedIndex为您提供所选标签

在tabBarController_shouldSelect_viewController方法中,您可以通过一些简单的计算设置所需的视图控制器。
如果你没有使用上述方法获得上述代码,你就会知道如何一起工作

答案 10 :(得分:0)

Swift 4.2

对我有用的解决方案是将UITabBarController子类化,并添加两个委托函数,如下所示:

import UIKit

class MyCustomTabBarController: UITabBarController, UITabBarControllerDelegate {
    var previousSelectedTabIndex:Int = 0

override func viewDidLoad() {
    super.viewDidLoad()
    self.delegate = self
}

func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    self.previousSelectedTabIndex = tabBarController.selectedIndex
}


override func tabBar(_ tabBar: UITabBar, didSelect item:
    UITabBarItem) {
    let vc = self.viewControllers![previousSelectedTabIndex] as! UINavigationController
    vc.popToRootViewController(animated: false)

}

}

确保将animation设置为false,否则会得到

 Unbalanced calls to begin/end appearance transitions for the targeted ViewController

答案 11 :(得分:0)

使用选定的视图控制器来popToRootViewController。基本上,您需要强制转换该实例。

快速

((selectedViewController) as! UINavigationController).popToRootViewController(animated: false)
//
// I just added extra line so the scroll bar won't annoy you.

答案 12 :(得分:0)

Xcode 11.5,Swift 5:

您不需要使用两个委托方法。仅一个就足够了:

extension CustomTabBarController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        if tabBarController.viewControllers?.firstIndex(of: viewController) == tabBarController.selectedIndex,
            let navigationController = viewController as? UINavigationController {
            navigationController.popToRootViewController(animated: true)
        }
    
        return true
    }
}

答案 13 :(得分:0)

//create a tabbar controller class set it to your TabbarController in storyboard
import UIKit

class MyTabbarViewController: UITabBarController,UITabBarControllerDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }
    
 
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
    {
        if let vc = viewController as? UINavigationController
        { vc.popToRootViewController(animated: false) }
    }

  

}