我遇到了一些我认为可能很容易的问题。我在根视图控制器中有一个表,当选择一行时,我按下一个新视图,然后从那里转到另一个选项卡。
我的问题是如何确保用户点击第一个标签后导航控制器会弹出到root?
答案 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) }
}
}