iOS7以上: 实现如“日历”的 NavigationBar
第一步,隐藏导航栏底部的分割线
如何隐藏导航栏底部的分割线(shadow image/ hairline)?
navigationBar.clipsToBounds = YES; //隐藏 navigationBar.clipsToBounds = NO; //显示
因为分割线是显示在导航栏外部的,已经超过了导航栏的高度,通过 [UIView setClipsToBounds:bool] 决定是否显示 View frame 之外的部分。
也可以根据这个分割线的特性获取 Ta 这个 View,然后通过 [UIView setHidden:hidden] 方法控制是否需要显示。
首先,Ta 是个一个 UIImageView, 并且 Ta 的 height 不大于 1:
- (UIImageView *)findHairlineFromView:(UIView *)view { if ([view isKindOfClass:[UIImageView class]] && view.frame.size.height <= 1.0) { return (UIImageView *)view; } for (UIView *subView in view.subviews) { UIImageView *imageView = [self findHairlineFromView:subView]; if (imageView) { return imageView; } } return nil; }
//在 viewDidLoad 方法中获取 hairline hairlineView = [self findHairlineFromView:self.navigationController.navigationBar]; //在 viewWillAppear: [hairlineView setHidden:YES]; //在 viewWillDisappear: [hairlineView setHidden:NO];
第二部,增加导航栏的“高度”
如果注意观察 apple 的官方应用,如 “日历” 或 “App Store”,会发现这其实不是一个导航栏 (NavigationBar),而是自定义的导航栏恰好顶在系统的导航栏下面,看起来好像一个。实际上是两个导航栏的合体。
如果只是改变系统导航栏的 Frame,会发现导航栏上 UIBarButtonItem 和 Title 始终都会挨着导航栏的下沿。所以,就考虑通过上面的方法实现。
先初始化一个自定义导航栏:
self.customNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 60)]; self.customNavigationBar.delegate = self; [self.view addSubview:self.customNavigationBar];
实现 <UINavigationBarDelegate> 中的方法
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }
效果: