關于UINavigationBar兼容iPhone X的轉場動畫

導航欄在實際應用中會有很多,跟隨scrollview改變其透明度或偏移的效果。以往是使用hide導航后,再使用自定的方式實現。但仔細觀察一些大的APP可以發現,頂部的items或背景都是有轉場效果的。所以,一直在考慮如何實現,同時可以兼容iPhone X。

方案

1、跟隨滾動時,導航欄偏移,這個可以直接通過改變導航欄frame的方式改變
2、透明度變化,最開始我的方案是通過原生方法,不斷根據透明度的值去生成新的圖片或背景色來修改,效果是可以實現的。但是在兩個controller之前轉場時,就會顯的非常木
3、最后還是使用了自定義背景view的方案來解決的,經測試在iphoneX上面也是完美的。
創建一個UINavigationBar的category,直接上代碼

static char customBackgroundImageViewKey;
/**
使用此方法,通過以下設置原生的背景圖及shadow為透明
[xxx setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
 [xxx setShadowImage:[UIImage new]];
*/
@implementation UINavigationBar (LGXBackground)

- (UIImageView *)customBackgroundImageView
{
    return objc_getAssociatedObject(self, &customBackgroundImageViewKey);
}
- (void)setCustomBackgroundImageView:(UIImageView *)customBackgroundImageView
{
    objc_setAssociatedObject(self, &customBackgroundImageViewKey, customBackgroundImageView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - 設置項
/// 設置背景色
- (void)lgx_setBackgroundColor:(UIColor *)backgroundColor
{
    [self checkOverlayView];
    [self.customBackgroundImageView setBackgroundColor:backgroundColor];
}
/// 設置背景圖
- (void)lgx_setBackgroundImage:(UIImage *)image
{
    [self checkOverlayView];
    [self.customBackgroundImageView setImage:image];
}
/// 設置背景alpha
- (void)lgx_setBackgroundAlpha:(float)alpha
{
    [self checkOverlayView];
    self.customBackgroundImageView.alpha = alpha;
}
/// 設置shadow
- (void)lgx_setShadowImage:(UIImage *)image
{
    
}
- (void)checkOverlayView
{
    if (!self.customBackgroundImageView) {
        UIView *contentView = self.subviews.firstObject;
        CGFloat width = CGRectGetWidth(self.bounds);
        CGFloat height = CGRectGetHeight(self.bounds) + [UIApplication sharedApplication].statusBarFrame.size.height;
        self.customBackgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, contentView.bounds.size.height - height, width, height)];
        self.customBackgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
        [contentView insertSubview:self.customBackgroundImageView atIndex:0];
    }
}
@end

4、至此就可以通過scrollView的變化來修改兩個屬性變化了,下面我們來說一下轉場動畫

轉場

其實轉場有很多種,我覺得這篇文章講的很好。有興趣的可以仔細閱讀一下。但是我使用了另一個API

UIViewController的 transitionCoordinator屬性

這個屬性向我們提供一個非常簡單的API,但是卻可以幫助我們實現一些轉場效果,下面貼下代碼。

// from controller
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        // change alpha or frame ...
          } completion:NULL];
}
// 同樣在 target controller 中也進行相應的代碼,只是改變的效果不同罷了。

是不是很簡單。效果非常的完美,在iPhone 10上面,也表現的很棒,看下效果圖

QQ20170920-175814.gif
QQ20170920-175707.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,287評論 25 708
  • 昨天 本來要和一個高中的老鐵一起打工(還沒有方向),突然一個老鐵問我要不要和他一起去北京混混,再三考慮然后同意了,...
    雷帥帥閱讀 167評論 0 1
  • 今天早晨5點40分準時起床,現在每天都是要6點鐘之前起來,孩子上學放在首席了,我現在成了孩子的陪讀和司機了,孩子的...
    周秀峰閱讀 317評論 1 2