Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.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
Iphone 选择选项卡时弹出到根视图_Iphone_Ios_Uinavigationcontroller_Uitabbarcontroller - Fatal编程技术网

Iphone 选择选项卡时弹出到根视图

Iphone 选择选项卡时弹出到根视图,iphone,ios,uinavigationcontroller,uitabbarcontroller,Iphone,Ios,Uinavigationcontroller,Uitabbarcontroller,我在一些我认为很容易的事情上遇到了一些麻烦。我的根视图控制器中有一个表,当选择一行时,我推送一个新视图,然后从那里转到另一个选项卡 我的问题是如何确保一旦用户点击第一个选项卡,导航控制器就会弹出到root 你想做的事情听起来有点奇怪。您是否阅读了关于组合UINAVIgationController和UITABBARController的人机界面指南 [self.navigationController popToRootViewControllerAnimated:NO]; 但是,您需要做的是

我在一些我认为很容易的事情上遇到了一些麻烦。我的根视图控制器中有一个表,当选择一行时,我推送一个新视图,然后从那里转到另一个选项卡


我的问题是如何确保一旦用户点击第一个选项卡,导航控制器就会弹出到root

你想做的事情听起来有点奇怪。您是否阅读了关于组合UINAVIgationController和UITABBARController的人机界面指南

[self.navigationController popToRootViewControllerAnimated:NO];

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

在选项卡栏上选择每个选项卡时,将调用以下委托

-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
将以下代码放入此委托方法中

if ([viewController isKindOfClass:[UINavigationController class]]) 
    {
        [(UINavigationController *)viewController popToRootViewControllerAnimated:NO];
    }
在我的应用程序上运行良好。

对于Swift爱好者:

import UIKit

class YourTabBarControllerHere: UITabBarController,
UITabBarControllerDelegate {

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

    func tabBarController(tabBarController: UITabBarController,
        didSelectViewController viewController: UIViewController) {
            if let vc = viewController as? UINavigationController {
                vc.popViewControllerAnimated(animated: false);
            }
    }
}

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

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

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tabBar addObserver:self forKeyPath:@"selectedItem" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}
当选择tabbar时,我们将使用以下方法处理:

-(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];
            }
        }
    }
}

UTabController建议使用不同的UX,让用户“跳转到根目录”。当切换回选项卡时,它会保留以前的完整UINav堆栈。如果他们第二次点击条形图项目(点击所选的选项卡),它才会弹出到根目录。那都是自动的。有些应用程序,比如instagram,允许第三次点击滚动到顶部


我建议坚持默认设置,因为这是用户所期望的。

下面的代码对我很有用。swift 3中的以下代码:

1> 子类UITabbarController并用一个iVAr实现下面两个方法:
类MyTabBarController:UITabBarController、UITabBarController Delegate{
var previousSelectedTabIndex:Int=-1
}

2> 在viewdidLoad中设置选项卡栏委托

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 method中,您可以通过一些简单的计算设置所需的视图控制器。
如果您没有获得上述代码,请同时使用上述两种方法,并了解Swift 3.1中这两种方法是如何协同工作的

将UITabbarController delegate添加到TabBar类:

类YourClass:UITabBarController,UITabBarControllerDelegate{

之后:

覆盖功能选项卡栏(选项卡栏:UITabBar,didSelectItem: (修道院院长){

}


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)

}

}
确保将“动画”设置为false,否则将

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

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

Swift

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

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)
    }
}
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) }
        }
    }
代码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
    }
}

如果你查看Apple的Phone.app,收藏夹和最近标签的行为与OP想要的是一样的。当你选择一个表行时,手机应用不会切换标签-这是我查询的行为,当用户点击不同的标签时,不会弹出根目录。啊,是的,OP的问题不完全是OP的意思“从那里我转到另一个选项卡"。用户是否选择了另一个选项卡或应用程序是否自动切换。这对我非常有帮助,可以根据我的要求在我的应用程序中正常工作。委托是什么文件?我尝试创建UINavigationController并将其指定为委托。我在viewDidLoad上看到它被调用,但将其指定为UITabBarDelegate或UITa的委托bBarControllerDelegate不调用此方法。我有点困惑。你能告诉我我在哪里添加此代码吗?对于那些无法使其不起作用的人,请尝试在头文件(.h)中添加
uitabarControllerDelegate
,并在实现文件(.m)中添加
self.tabBarController.delegate=self;
。将“动画”更改为“否”实际上对我有帮助。当我将“动画”设置为“是”时,我的选项卡栏或导航控制器中的任何其他按钮都不起作用。当OP询问根控制器时,它应该是(在Swift 3语法中)
vc.poptrootviewcontroller(动画:false)
此方法记录目标ViewController开始/结束外观转换的不平衡调用,即使它确实有效。我正在尝试找到一种不会记录错误的解决方案。
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
    }
}
//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) }
    }

  

}