我是iPhone开发的新手,想询问导航控制器。如何使导航控制器固定在整个应用程序上,如facebook导航栏。它始终在导航栏中显示通知,朋友和消息。
我正在尝试将自定义视图放在titleView中,但每次导航推送新视图时它都会消失?
答案 0 :(得分:6)
这里发布了一个类似的问题(https://stackoverflow.com/questions/16773312/facebook-like-navigationbar),不幸的是它很快就关闭了。我在这里兑现了它想要的荣耀。
如果您考虑使用基于Tab的应用程序(带有隐藏标签)进行导航,则可以轻松实现持久性导航栏。
使用故事板:
将Nav 2设置为Tab Bar控制器的第一个(选项卡)视图控制器。
对于导航1:在属性检查器下 - >导航控制器 - >栏可见性,确保该框勾选(以便显示导航栏)。
如果您运行该应用,您应该会看到标签栏的标题可见,并且隐藏了视图控制器的标题。这为您提供了持久导航栏的基础知识。您可以从My View Controller将PUSHing视图保持在堆栈中,并且它将保持持久性。呈现MODAL视图将带来新的上下文,因此失去了持久性。如果重复这些步骤,您应该能够为模态显示的视图创建相同的效果。
此答案的其余部分涉及隐藏标签栏和管理导航栏元素。
这很好,但是如何将自定义视图放在导航栏中,以及如何隐藏该标签栏?
创建UITabBarController的子类,并将其分配给故事板中的Tab Bar控制器。
隐藏标签栏
您可以通过各种方式隐藏标签栏。如果你有兴趣,可以点击这里(How to hide uitabbarcontroller);这个小片段改编自我在该主题中的答案:
CGRect screenRect = [[UIScreen mainScreen] bounds];
float fHeight = screenRect.size.height;
if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) )
{
fHeight = screenRect.size.width;
}
for(UIView *view in self.view.subviews){
if([view isKindOfClass:[UITabBar class]]){
[view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)];
}else{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)];
}
}
这会将Tab Bar移出视图并调整视图大小以填充空间(没有动画,就像它从未出现过一样)。将此代码段添加到viewDidLoad
的开头,以便将该栏移开。
导航栏中的自定义视图
在TB子类的viewDidLoad
方法中,您可以使用按钮创建自定义视图,并将其添加到导航栏,如下所示:[self.navigationItem setTitleView:myCustomTitleView];
简单。
如果没有正确显示,请确保在将其设置为titleView之前定义其框架。然后在添加它之后,使用[myCustomTitleView sizeToFit]
使其紧贴导航栏。
设置栏按钮项
设置左右栏按钮项目需要对符号进行少量更改。通常,您可以通过引用self.navigationItem.leftBarButtonItem
来设置左侧栏按钮。该引用实际上指向HIDDEN导航栏的左侧栏按钮。要访问VISIBLE导航栏,请使用self.tabBarController.navigationItem.leftBarButtonItem
。简单!
处理丢失的栏后退按钮项
您使用持久性导航栏牺牲的一件事是管理推送的视图。像后箭头这样的东西不会显示(它们出现在隐藏的导航栏上)。您可以通过将TabBarController子类设置为其视图控制器(应该都是UINavigationControllers)的委托来克服这个问题。
for (UINavigationController *navController in self.viewControllers) {
navController.delegate = self;
}
每当这些UINavigationControllers中的任何一个推送另一个视图时,您都可以使用此委托方法拦截此操作:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
在这里,您可以查看推送的视图控制器数量:
if(navigationController.viewControllers.count > 1){
//create a custom back button here and add it to the nav bar
}else{
//set the left bar button (where the custom back button would sit) to nil
}
自定义后退按钮可以调用选项卡栏控制器子类中的方法,该方法告诉当前选定的视图控制器弹出其当前视图。
Facebook是这样做的吗?
我无法验证这是Facebook做过的方式(可能不是),但它会达到类似的效果。我已经在我的最新应用程序(http://www.waterboyapp.com)中有效地使用了它,Apple很快就被苹果公司接受了。我希望之前有人在网上发布过这个,因此我的贡献是节省了数小时/天的搜索时间。
<强>除了强>
此实现的额外好处(除了简单和优雅之外)是您可以将多个视图控制器链接到选项卡栏。通过for循环和一点创造力,您可以在导航栏中重新创建自定义按钮(基于选项卡),这些按钮执行与标签栏相同的功能。这样可以节省屏幕空间(因为标签栏非常大),并且仍然使用标签栏来执行视图交换。
答案 1 :(得分:0)
您应该理解的是,显示的UINavigationBar是导航控制器层次结构顶部的视图控制器的属性。根据您的理解,您可以尝试自定义每个视图控制器的UINavigationBar的titleView,例如在viewWillAppear。您可以使用
访问导航栏self.navigationController.navigationBar
其中self是加载的视图控制器引用。
对于你想在屏幕上的某个地方拥有持久性视图的情况,其中一个解决方案如下:在app-delegate类声明一个属性,在根视图之后将视图直接添加到窗口,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// something here ...
// root view controller
[window addSubview:myRootViewController.view];
// toolbar
MyToolbar * tb = [MyToolbar new];
tb.barStyle = UIBarStyleDefault;
[tb sizeToFit];
tb.frame = CGRectMake(0, 0, 320, 70);
[window addSubview:tb];
self.globalToolBar = tb;
[tb release];
然后您可以通过这种方式从任何视图更新工具栏(在这种情况下,它可能是任何视图):
[[[[UIApplication sharedApplication] delegate] globalToolBar] updateRightButtonItem]
因此,您需要使用MyToolbar继承UIToolBar,在那里添加一些UI方法,例如updateRightButtonItem,您可能还需要创建委托或处理来自工具栏的通知,以捕获顶视图控制器上的事件。 / p>
这样,视图控制器的视图将使用导航控制器逻辑进行动画处理,但工具栏是一个窗口子视图,并且不会被导航操作自动更改。
答案 2 :(得分:0)
这对我有用:
toolBar = [[UIView alloc]initWithFrame:CGRectMake(105, 20, 105, 44)];
notificationsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
messagesBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[notificationsBtn setImage:[UIImage imageNamed:@"notifications-icon.png"] forState:UIControlStateNormal];
[notificationsBtn setFrame:CGRectMake(35, 0, 35 , 44)];
[notificationsBtn addTarget:self action:@selector(showNotifications:) forControlEvents:UIControlEventTouchUpInside];
[messagesBtn setImage:[UIImage imageNamed:@"messages-icon.png"] forState:UIControlStateNormal];
[messagesBtn setFrame:CGRectMake(70, 0, 35 , 44)];
[messagesBtn addTarget:self action:@selector(showMessages:) forControlEvents:UIControlEventTouchUpInside];
[toolBar addSubview:notificationsBtn];
[toolBar addSubview:messagesBtn];
[_window.rootViewController.view addSubview:toolBar];