如何在iOS中从导航控制器中删除视图时删除导航栏项?

时间:2013-11-06 19:22:29

标签: ios uiviewcontroller uinavigationcontroller uinavigationbar uinavigationitem

我搜索并发现了几篇关于如何从导航控制器堆栈中删除视图的帖子。我已经实现了这里找到的一种技术: 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:animated:直接在由控制器管理的UINavigationBar上。“

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

1 个答案:

答案 0 :(得分:0)

有点困惑你想在这里做什么......但你做的事情看起来很尴尬。通常当你遇到这样的问题时,你的UI就会出现问题。

登录屏幕通常是模态视图,而不是导航控制器的一部分。你在做什么,你真的不应该这样做。

也许从主屏幕登录一个模态,并在主屏幕上为您的登录屏幕创建一个委托。登录后,请致电代表&解雇模态。然后在Main上的委托侦听器方法中,如果登录成功,请按Admin屏幕..然后当您回击时,您将不必绕过登录。

如果这是有道理的。

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