将 UIViewController 推送到 UINavigationController(也在 UITabBarController 中)

Posted

技术标签:

【中文标题】将 UIViewController 推送到 UINavigationController(也在 UITabBarController 中)【英文标题】:Pushing a UIViewController onto a UINavigationController (which also inside a UITabBarController) 【发布时间】:2012-10-21 19:04:29 【问题描述】:

我在 AppDelegate 中以编程方式创建了一个 UITabBarController。我还创建了两个 UINavigationController,其中包含一些 UIViewController。我将导航控制器添加到 UITabBarController 上,如下所示:

    BVMapViewController *mapViewController = [[[BVMapViewController alloc] initWithNibName:@"BVMapViewController_iPhone" bundle:nil] autorelease];
    BVFavoritesViewController *favoritesViewController = [[[BVFavoritesViewController alloc] initWithNibName:@"BVFavoritesViewController_iPhone" bundle:nil] autorelease];

    UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:mapViewController] autorelease];
    [navigationController setToolbarHidden:YES];
    UINavigationController *navigationControllerForFavorites = [[[UINavigationController alloc] initWithRootViewController:favoritesViewController] autorelease];

    self.tabBarController = [[[UITabBarController alloc] init] autorelease];
    NSArray* controllers = [NSArray arrayWithObjects:navigationController, navigationControllerForFavorites, nil];
    self.tabBarController.viewControllers = controllers;
    [self.window setRootViewController:self.tabBarController];

结果可以正常创建一个带有两个导航控制器的标签栏控制器。

问题如下: 第一个 UINavigationController 包含一个 UIViewController,里面有一个 MKMapView。该地图显示了一堆 POI,因此当您点击其中一个时,应用程序会向 Web 服务 (在后台) 发送请求,一旦完成,它就会通知视图控制器推送另一个UIViewController 进入导航堆栈以显示有关该 POI 的更多信息,

[self.navigationController pushViewController:self.stationViewController
                                     animated:YES];

这里出现以下错误:

_WebTryThreadLock(bool), 0x11d9b560: 试图从主线程或web线程以外的线程获取web lock。这可能是从辅助线程调用 UIKit 的结果。现在崩溃... 1 0x58a76a9 网络线程锁 2 0x5bfdfe -[UITextView _updateForNewSize:withOldSize:] 3 0x5c00b4 -[UITextView 设置帧:] 4 0x4c59df UIViewCommonInitWithFrame 5 0x4c5bae-[UIView initWithCoder:] 6 0x4d9fb7 -[UIScrollView initWithCoder:] 7 0x5bc851 -[UITextView initWithCoder:] 8 0x7b1a02 UINIbDecoderDecodeObjectForValue 9 0x7b10e5 -[UINibDecoder decodeObjectForKey:] 10 0x6a2648 -[UIRuntimeConnection initWithCoder:] 11 0x7b1a02 UINIbDecoderDecodeObjectForValue 12 0x7b1418 UINIbDecoderDecodeObjectForValue 13 0x7b10e5 -[UINibDecoder decodeObjectForKey:] 14 0x6a1aa3 -[UINib 实例化WithOwner:选项:] 15 0x566e37 -[UIViewController _loadViewFromNibNamed:bundle:] 16 0x567418 -[UIViewController 加载视图] 17 0x567648 -[UIViewController loadViewIfRequired] 18 0x567882 -[UIViewController 视图] 19 0x567b2a -[UIViewController 内容滚动视图] 20 0x57eef5 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] 21 0x57efdb -[UINavigationController _layoutViewController:] 22 0x57f286 -[UINavigationController _updateScrollViewFromViewController:toViewController:] 23 0x57f381 -[UINavigationController _startTransition:fromViewController:toViewController:] 24 0x57feab -[UINavigationController startDeferredTransitionIfNeeded:] 25 0x5804a3 -[UINavigationController pushViewController:transition:forceImmediate:] 26 0x580098 -[UINavigationController pushViewController:animated:] 27 0x386f -[BVMapViewController parserDidFinishWithStation:] 28 0x785c -[BVParser 解析站:] 29 0xf8a0d5 -[NSThread 主线程] 30 0xf8a034 NSThread_main 31 0x94e53ed9 _pthread_start

我尝试在主线程上执行此操作,但推送的控制器的视图全黑。

提前谢谢你,祝你有美好的一天。

【问题讨论】:

【参考方案1】:

好吧,正如您在问题中提到的那样,您必须将视图控制器推送到主线程上。与 UIKit 的任何交互都必须在主线程上完成。

至于为什么它显示为黑色,这是一个不同的问题,您需要通过标准故障排除技术来解决。一旦它在主线程上并且正确运行,就在所显示的类的各种方法(viewDidLoad 等)上设置断点并查看它在哪里出错。

【讨论】:

非常感谢。出现黑屏问题是因为我没有在 Interface Builder 中设置视图的属性。

以上是关于将 UIViewController 推送到 UINavigationController(也在 UITabBarController 中)的主要内容,如果未能解决你的问题,请参考以下文章

将 UIBarButtonItem 添加到 UIViewController 推送到 UINavigation 控制器

将 UIViewController 推送到导航堆栈时如何显示选项卡栏

将不同方向的 UIViewController 推送到上一个

从弹出窗口将 UIViewController 推送到 UINavigationController

将 UIViewController 推送到 UINavigationController(也在 UITabBarController 中)

将 UIViewController 推送到 UINavigationController 时动画挂起