【问题标题】:popToRootViewController when another tab is selected选择另一个选项卡时的 popToRootViewController
【发布时间】:2015-12-03 00:40:42
【问题描述】:

上下文:

我同时使用 TabViewController 和 NavigationController。这两个选项卡是RECENTPOPULAR,它们显示帖子列表。想象一下,您在RECENT 选项卡中并单击一个帖子,然后您进入postsShow 视图。所以你在导航堆栈中更深一层。当您转到POPULAR 选项卡并返回RECENT 选项卡时,您仍然会看到您之前单击的帖子。但我想显示一个帖子列表。

我正在尝试什么:

我设置PostsShowViewController a TabBarControllerDelegate和选择选项卡项时,我正在尝试弹出它的根视图控制器。然后,当用户返回时,他会看到 rootViewController,它是帖子列表,而不是 PostsShow 视图。

代码:

viewDidAppear self.tabBarController.delegate = self;

viewDidDisappear self.tabBarController.delegate = nil;

标题 UITabBarControllerDelegate

- (BOOL) tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
    [self.navigationController popToRootViewControllerAnimated:NO];
    return YES;
}

它是如何工作的:

  1. 转到最近的标签
  2. 点击帖子进入 PostsShow 视图
  3. 转到热门标签
  4. 返回最近的标签(我希望看到帖子列表而不是 PostsShow 视图)
  5. 错误! EXC_BAD_ACCESS

编辑: 按照答案建议的做法,我的行为稍微好一点,但最终还是会出现错误。

代码

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    UINavigationController *navigation = (UINavigationController*) viewController;
    [navigation popToRootViewControllerAnimated:NO];
}
  1. 转到最近的标签
  2. 点击帖子进入 PostsShowview
  3. 转到热门标签
  4. 返回最近的标签
  5. 我看到了一个帖子列表(没有错误!)
  6. 返回热门标签:ERR_BAD_ACCESS!

编辑: 这是我的故事板

EDIT2:

全栈跟踪:

* thread #1: tid = 0x4a37c, 0x0000000197bb7bd0 libobjc.A.dylib`objc_msgSend + 16, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10)
    frame #0: 0x0000000197bb7bd0 libobjc.A.dylib`objc_msgSend + 16
    frame #1: 0x000000018ab52078 UIKit`-[UITabBarController _tabBarItemClicked:] + 104
    frame #2: 0x000000018a9891ec UIKit`-[UIApplication sendAction:to:from:forEvent:] + 96
    frame #3: 0x000000018ab51fb4 UIKit`-[UITabBar _sendAction:withEvent:] + 468
    frame #4: 0x000000018a9891ec UIKit`-[UIApplication sendAction:to:from:forEvent:] + 96
    frame #5: 0x000000018a9722c8 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 612
    frame #6: 0x000000018ab51bec UIKit`-[UITabBar(Static) _buttonUp:] + 128
    frame #7: 0x000000018a9891ec UIKit`-[UIApplication sendAction:to:from:forEvent:] + 96
    frame #8: 0x000000018a9722c8 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 612
    frame #9: 0x000000018a988b88 UIKit`-[UIControl touchesEnded:withEvent:] + 592
    frame #10: 0x000000018a947da8 UIKit`_UIGestureRecognizerUpdate + 8536
    frame #11: 0x0000000185e8fff0 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
    frame #12: 0x0000000185e8cf7c CoreFoundation`__CFRunLoopDoObservers + 360
    frame #13: 0x0000000185e8d35c CoreFoundation`__CFRunLoopRun + 836
    frame #14: 0x0000000185db8f74 CoreFoundation`CFRunLoopRunSpecific + 396
    frame #15: 0x000000018f8136fc GraphicsServices`GSEventRunModal + 168
    frame #16: 0x000000018a9bad94 UIKit`UIApplicationMain + 1488
  * frame #17: 0x0000000100023ff4 toaster-objc`main(argc=1, argv=0x000000016fdeba50) + 124 at main.m:14
    frame #18: 0x000000019824ea08 libdyld.dylib`start + 4

【问题讨论】:

  • 你的层次结构是什么? TabBarViewController -> NavigationController?
  • @NickCatib 是的。每个 tabItem 都连接到 NavigationController。
  • 看到这个链接可能对你有帮助stackoverflow.com/questions/21017985/…
  • 你不应该把viewController转换成UINavigationController然后pop吗?
  • 我试过这样做(@coder1010 的回答所描述的方式),结果如下: 1. 转到最近的选项卡 2. 单击帖子转到 PostsShowview 3. 转到热门选项卡 4. 转到返回最近的标签 5. 我看到一个帖子列表(没有错误!) 6. 返回热门标签:ERR_BAD_ACCESS!

标签: ios objective-c


【解决方案1】:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    if ([viewController isKindOfClass:[UINavigationController class]]) {
        [(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
    }
}

【讨论】:

    【解决方案2】:

    试试这个:

    - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    
    if ([viewController isKindOfClass:[UINavigationController class]])
    {
        UINavigationController *navController = (UINavigationController *)viewController;
    
        [navController popToRootViewControllerAnimated:NO];
    
    }
    }
    

    【讨论】:

    • 感谢您的回答。请查看我更新的问题。
    • 可能是您在热门标签上没有导航控制器。请尝试在下面添加我在回答中提到的 if 条件 if ([viewController isKindOfClass:[UINavigationController class]])
    • 我愿意(请参阅更新后的问题),我也尝试添加条件:(
    【解决方案3】:

    这是我在 swift 中的做法:

    func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
    
        self.tabBarSelectedIndex = tabBarController.selectedIndex
        var navigation = viewController as! UINavigationController
        navigation.popToRootViewControllerAnimated(false)
        // rest of the logic
    }
    

    在 Objective-C 中类似:

    - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
        self.tabBarSelectedIndex = tabBarController.selectedIndex;
        UINavigationController *navigation = (UINavigationController*) viewController;
        [navigation popToRootViewControllerAnimated:NO];
    }
    

    请注意,我为 UITabBarController 使用了 didSelectViewController 方法。

    您可以查看here:

    【讨论】:

    • 感谢您的回答。请查看我更新的问题。
    • 这可能是因为您在一个选项卡上而不是另一个选项卡上有 UINavigationController。您只能对某些 selectedIndex 执行此弹出操作,即 if (tabBarController.selectedIndex == 0) 强制转换为导航和弹出。
    • 另外,您可以启用异常断点来确定它在哪里崩溃。
    • 发生在UIApplicationMain。所有选项卡都连接到它们自己的导航控制器。
    • 是的,因为它是实际捕获它的主线程。如果你试试这个:stackoverflow.com/questions/17802662/… 你会得到它在标签栏中失败的地方。此外,您可以在发生崩溃后在控制台中写入“bt”,以便查看完整的堆栈跟踪
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    相关资源
    最近更新 更多