如何iphone Facebook应用程序使导航栏固定

时间:2012-03-14 15:02:52

标签: iphone facebook uinavigationcontroller xcode4.2

我是iPhone开发的新手,想询问导航控制器。如何使导航控制器固定在整个应用程序上,如facebook导航栏。它始终在导航栏中显示通知,朋友和消息。

我正在尝试将自定义视图放在titleView中,但每次导航推送新视图时它都会消失?

3 个答案:

答案 0 :(得分:6)

这里发布了一个类似的问题(https://stackoverflow.com/questions/16773312/facebook-like-navigationbar),不幸的是它很快就关闭了。我在这里兑现了它想要的荣耀。

如果您考虑使用基于Tab的应用程序(带有隐藏标签)进行导航,则可以轻松实现持久性导航栏。

使用故事板:

Simple setup in Storyboard

  1. 创建一个新的UINavigationController(Nav 1)。
  2. 将UITabController设置为Nav 1的根视图控制器。(Tab Bar)请注意,它将拥有自己的导航栏(我将其标记为“Persistent Nav Bar”)。
  3. 创建另一个UINavigationController(导航2)。
  4. 将您选择的视图控制器(My View Controller)设置为Nav 2的根视图控制器。
  5. 将Nav 2设置为Tab Bar控制器的第一个(选项卡)视图控制器。

  6. 对于导航1:在属性检查器下 - >导航控制器 - >栏可见性,确保该框勾选(以便显示导航栏)。

  7. 对于导航2:在属性检查器下 - >导航控制器 - > 栏可见性,确保该框未勾选(以便它 不会显示其导航栏。)
  8. 如果您运行该应用,您应该会看到标签栏的标题可见,并且隐藏了视图控制器的标题。这为您提供了持久导航栏的基础知识。您可以从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];