Navigation Bar 透明动画实现
目前很流行流行的UI效果,监听滚动,导航条渐隐的UI效果实现,很多APP都有实现,比如美团外卖的首页模块,新浪微博的个人详情页面。
设置self.view全屏
- (void)viewDidLoad
{
[super viewDidLoad];
[self configVCFullScreen];
...
}
/// 设置 self.view 全屏
- (void)configVCFullScreen
{
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
self.modalPresentationCapturesStatusBarAppearance = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
}
设置 Naivgation Bar 的透明度
- (void)configNavigationBar
{
...
// KVO 监听 offset ,计算透明图
@weakify(self);
[[[RACObserve(self.tableView, contentOffset) takeUntil:[self rac_signalForSelector:@selector(viewWillDisappear:)]]filter:^BOOL(NSValue *value) {
return value.CGPointValue.y <= 500;
}] subscribeNext:^(NSValue *value) {
@strongify(self);
CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
[self setNavigationBarAlpha:alpha];
...
}];
}
- (void)setNavigationBarAlpha:(CGFloat)alpha
{
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor colorWithWhite:1.0f alpha:alpha]] forBarMetrics:UIBarMetricsDefault];
}
去掉 Navigation Bar 的底阴影线
/// 去掉 navigation bar 底线
self.navigationController.navigationBar.shadowImage = [UIImage new];
如何设置 Status Bar的颜色
// 设置Status Bar 字体为黑色
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
// 设置Status Bar 字体为白色
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
完整细节代码
#pragma mark - View Controller Life Cycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.forbidAutoGa = YES;
// 导航栏透明
[self configVCFullScreen];
...
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 设置透明度相关
[self configNavigationBar];
...
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
if (alpha < 0.5) {
// viewWillAppear 里面更改没有效果,可能是我们公司业务的父类有处理
[self setupLightStyleAppearance];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//页面消失前恢复之前的设置,避免对其他页面造成影响
[self resumeNavigationBar];
}
#pragma mark - Navigation Bar config
- (void)configNavigationBar
{
if (!_oldShadowImage) {
self.oldShadowImage = [self.navigationController.navigationBar shadowImage];
}
if (!_oldBackImage && [self.navigationItem.leftBarButtonItem.customView isKindOfClass:[UIButton class]]) {
self.backBtn = self.navigationItem.leftBarButtonItem.customView;
self.oldBackImage = self.backBtn.imageView.image;
}
@weakify(self);
[[[RACObserve(self.tableView, contentOffset) takeUntil:[self rac_signalForSelector:@selector(viewWillDisappear:)]]filter:^BOOL(NSValue *value) {
return value.CGPointValue.y <= 500;
}] subscribeNext:^(NSValue *value) {
@strongify(self);
CGFloat alpha = MAX(0, self.tableView.contentOffset.y / ([UIScreen width] / 16.0f * 9.0f - 64));
[self setNavigationBarAlpha:alpha];
[self setupTopBarsAppearanceWithAlpha:alpha];
}];
}
- (void)configVCFullScreen
{
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
self.modalPresentationCapturesStatusBarAppearance = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
}
- (void)setNavigationBarAlpha:(CGFloat)alpha
{
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor colorWithWhite:1.0f alpha:alpha]] forBarMetrics:UIBarMetricsDefault];
}
- (void)setupTopBarsAppearanceWithAlpha:(CGFloat)alpha
{
if (alpha < 0.5 && self.navigationController.navigationBar.shadowImage == self.oldShadowImage) {
[self setupLightStyleAppearance];
} else if ( alpha > .5 && self.navigationController.navigationBar.shadowImage != self.oldShadowImage) {
[self setupDarkStyleAppearance];
}
}
- (void)setupLightStyleAppearance
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];//!< statusbar
self.navigationController.navigationBar.shadowImage = [UIImage new]; //!< navigation bar 底线
self.title = @"";
[self.backBtn setImage:[UIImage imageNamed:R_hotel_title_icon_back_light] forState:UIControlStateNormal];
[self.buttonForShare setImage:[UIImage imageNamed:R_hotel_title_icon_share_light] withHighLightStyle:ButtonHighLightStyleDark];
}
- (void)setupDarkStyleAppearance
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
self.navigationController.navigationBar.shadowImage = self.oldShadowImage;
self.title = self.product.title;
[self.backBtn setImage:self.oldBackImage ? : [UIImage imageNamed:@"detail_topbar_icon_back"] forState:UIControlStateNormal];
[self.buttonForShare setImage:[UIImage imageNamed:R_Title_icon_Share] withHighLightStyle:ButtonHighLightStyleDark];
}
- (void)resumeNavigationBar
{
[self setNavigationBarAlpha:1];
[self.navigationController.navigationBar setShadowImage:self.oldShadowImage];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}