【问题标题】:How to also remove navigation bar item when removing a view from navigation controller in iOS?从 iOS 中的导航控制器中删除视图时如何删除导航栏项目?
【发布时间】:2013-11-06 19:22:29
【问题描述】:

我搜索并找到了几篇关于如何从导航控制器堆栈中删除视图的帖子。我已经实现了这里找到的一种技术: How can I remove a view from navigation controller。但是,当视图从堆栈中删除时,相应的 UINavigationItem 并未从导航栏中删除,因此我的导航栏与当前视图不同步。

具体来说,我的故事板上有一系列受导航控制器控制的视图。打开视图允许用户在要遵循的两个分支之一之间进行选择。第一个分支允许用户接收和显示来自 iPhone 或 iPad 通过 Wi-Fi 连接的嵌入式系统的传感器数据。另一条路径允许用户以管理员身份登录,并向外部嵌入式系统发送一些配置命令。

如果用户选择管理路线,他们将遵循以下屏幕顺序:Main->Administrator Login->Administration。进入管理视图后,用户可以执行多项任务。我想要做的是当他们返回 Main 时跳过管理员登录屏幕,然后沿着另一条路径(查看流式传感器数据)。在管理视图中,我使用此代码从堆栈中删除了管理员登录视图

- (void)viewDidLoad
{
[super viewDidLoad];

NSMutableArray *navStack = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
NSMutableArray *navBarBrian = [[NSMutableArray alloc] initWithArray: [[[self navigationController] navigationBar] items] ];
UINavigationBar *navBar = [[UINavigationBar alloc] init];
navBar = self.navigationController.navigationBar;
NSLog(@"navStack = %@", navStack);
NSLog(@"navBar = %@", [[self navigationController] navigationBar]);
NSLog(@"navBarItems = %@", [[[self navigationController] navigationBar] items]);
NSLog(@"navBarBrian = %@", navBarBrian);
NSLog(@"navBarList = %@", navBar);
[navStack removeObjectAtIndex: [navStack count] - 2];
[navBarBrian removeObjectAtIndex:[navBarBrian count] - 1];
//    self.navigationController.viewControllers = navStack;
[self.navigationController setViewControllers:navStack animated:NO];    

//    [navBar popNavigationItemAnimated:NO];
//    [[[self navigationController] navigationBar] popNavigationItemAnimated:NO];
//    [[[self navigationController] navigationBar] setItems:navBarBrian animated:NO]; 
NSLog(@"navStack = %@", navStack);
NSLog(@"navBar = %@", [[self navigationController] navigationBar]);
NSLog(@"navBarItems = %@", [[[self navigationController] navigationBar] items]);
NSLog(@"navBarBrian = %@", navBarBrian);

}

因此,当我从“管理”视图返回时,应用确实会转到主视图屏幕。但是导航栏中的标题仍然显示管理员登录,并且有一个指向 Main 的后退按钮。我尝试从导航栏本身弹出导航项,但这会引发异常。我可以获取导航项列表,将它们存储在 navBarBrian 中,然后从我自己的 navBarBrian 数组中删除管理员登录屏幕的导航项。例如,在我删除 navBarBrian 中的对象之前,我有:

2013-11-06 11:59:25.457 BikeComm[703:a0b] navBarItems = ( "UINavigationItem: 0xa8a4cd0", “UINavigationItem:0xa8c4f40” )

2013-11-06 11:59:25.457 BikeComm[703:a0b] navBarBrian = ( "UINavigationItem: 0xa8a4cd0", “UINavigationItem:0xa8c4f40” )

之后,删除我有

2013-11-06 11:59:25.458 BikeComm[703:a0b] navBarItems = ( "UINavigationItem: 0xa8a4cd0", “UINavigationItem:0xa8c4f40” )

2013-11-06 11:59:25.459 BikeComm[703:a0b] navBarBrian = ( “UINavigationItem:0xa8a4cd0” )

但是我无法使用 setItems 方法将 navBarBrian 的内容存储回导航栏,因为这也会引发异常:“由于未捕获的异常 'NSInternalInconsistencyException' 而终止应用程序,原因:'无法调用 setItems:动画:直接在控制器管理的 UINavigationBar 上。”

那么从各自的堆栈中删除视图和导航项的技巧是什么?

【问题讨论】:

    标签: ios uiviewcontroller uinavigationcontroller uinavigationbar uinavigationitem


    【解决方案1】:

    有点困惑你想在这里做什么......但你的所作所为似乎很尴尬。通常,当您遇到此类问题时,您的 UI 存在缺陷。

    登录屏幕通常是模态视图,而不是导航控制器的一部分。你正在做的事情,你永远不应该真的去做。

    也许从您的主屏幕使登录成为一个模式,并为您的登录屏幕创建一个代理,并在您的主屏幕上收听。登录后,调用委托并关闭模式。然后在 Main 上的委托侦听器方法中,如果登录成功,则推送 Admin 屏幕。然后当您回击时,您将不必绕过登录。

    如果这有意义的话。

    我还建议阅读 iOS Human Interface Guidelines 以了解哪些 UI 元素最适合哪些情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      相关资源
      最近更新 更多