iOS Swift airbnb NavigationBar外观:隐藏导航栏 - >叠加标签但图像

时间:2016-08-26 09:51:24

标签: ios swift animation navigationbar airbnb

我已经尝试了一点点复制(或者至少有一个类似的工作示例)airbnb navigationBar。对于那些不了解应用程序的人,请参阅以下屏幕截图:

airbnb navigationBar start

airbnb navigationBar overlay

您可能会看到导航栏首先处于隐藏状态,然后位于图像后面,但覆盖了标题标签。我非常喜欢动画如何将导航栏平滑过渡到前面。

我想用

做这件事
  1. 隐藏导航栏
  2. 在navigationBar中以淡入淡出的确切位置开始:使navigationBar透明并增加alpha
  3. 在动画结束时显示默认的navigationBar
  4. 实现如下:https://github.com/mbecker/AirbnbCopy

    import UIKit
    
    private let kTableHeaderHeight: CGFloat = 300.0
    private let kTableHeaderCutAway: CGFloat = 60.0
    
    class MainViewController: UIViewController, UIScrollViewDelegate {
    
        @IBOutlet var headerView: UIView!
        @IBOutlet weak var scrollView: UIScrollView!
        @IBOutlet weak var parkHeading: UILabel!
        @IBOutlet weak var parkImage: UIImageView!
    
        var headerMaskLayer: CAShapeLayer!
        // create background images for the navigation bar
        var navBarImage = UIImage().imageWithColor(UIColor(red:0.11, green:0.64, blue:0.98, alpha:0.0))
        var gradientImage32 = UIImage().imageWithColor(UIColor(red:0.11, green:0.64, blue:0.98, alpha:0.0))
    
        let image = UIImage(named: "bg-addo")
        let overlay: UIView = UIView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.height, 400))
    
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            scrollView.delegate = self
    
            // Adjust view
            self.automaticallyAdjustsScrollViewInsets = false
    
            // NavigationBar
            let attrs = [
                NSForegroundColorAttributeName : UIColor.blackColor(),
                NSFontAttributeName : UIFont(name: "HelveticaNeue-Bold", size: 17)!
            ]
            self.navigationController!.navigationBar.titleTextAttributes = attrs
            self.navigationController!.navigationBar.hidden = true
            self.navigationController!.navigationBar.setBackgroundImage(navBarImage, forBarMetrics: .Default)
            self.navigationController!.navigationBar.setBackgroundImage(navBarImage, forBarMetrics: .Compact)
    //        self.navigationController!.navigationBar.shadowImage = UIImage()
            self.navigationController!.navigationBar.barStyle = .Default
    
    
            // Header
            overlay.backgroundColor = UIColor(red:0.04, green:0.28, blue:0.44, alpha:0.4)
            parkImage.addSubview(overlay)
            parkImage.image = image?.imageWithAlpha(1)
    
            headerMaskLayer = CAShapeLayer()
            headerMaskLayer.fillColor = UIColor.blackColor().CGColor
    
            headerView.layer.mask = headerMaskLayer
            updateHeaderView()
    
        }
    
        func scrollViewDidScroll(scrollView: UIScrollView) {
    
            let heightShowNavBarStart   = kTableHeaderHeight - kTableHeaderCutAway - parkHeading.frame.height - 66
            let heightShowNavBarEnd     = kTableHeaderHeight - kTableHeaderCutAway - 66
    
    
            print("scrollView.contentOffset.y   -   \(scrollView.contentOffset.y)")
            print("heightShowNavBarStart        -   \(heightShowNavBarStart)")
            print("heightShowNavBarEnd          -   \(heightShowNavBarEnd)")
    
    
    
            let base        = parkHeading.frame.height
            let counter     = heightShowNavBarEnd - scrollView.contentOffset.y
            var alpha       = counter / base
            var navigationBarHidden = false;
    
            if(scrollView.contentOffset.y >= heightShowNavBarStart && scrollView.contentOffset.y <= heightShowNavBarEnd){
    
            } else if (scrollView.contentOffset.y < heightShowNavBarStart ){
                navigationBarHidden = true
                alpha = 1
            } else if(scrollView.contentOffset.y > heightShowNavBarEnd) {
                navigationBarHidden = false
                alpha = 0
            }
            print("alpha                - \(alpha)")
            print("navigationBarHidden  - \(navigationBarHidden)")
    
    
            self.navigationController!.navigationBar.hidden = navigationBarHidden
    
            if(!navigationBarHidden && alpha == 0){
                // Show navigationBar && hide headerView parkImage
                parkImage.hidden = true
                self.navigationController!.navigationBar.setBackgroundImage(nil, forBarMetrics: .Default)
                self.navigationController!.navigationBar.setBackgroundImage(nil, forBarMetrics: .Compact)
                self.navigationController!.navigationBar.barStyle = .Default
            } else {
                parkImage.hidden = false
                parkImage.image = image?.imageWithAlpha(alpha)
                navBarImage = UIImage().imageWithColor(UIColor(red:0.96, green:0.96, blue:0.98, alpha: 1 - alpha))
                self.navigationController!.navigationBar.setBackgroundImage(navBarImage, forBarMetrics: .Default)
                self.navigationController!.navigationBar.setBackgroundImage(navBarImage, forBarMetrics: .Compact)
                overlay.backgroundColor = UIColor(red:0.04, green:0.28, blue:0.44, alpha: alpha * 0.4)
            }
    
    
        }
    
        func updateHeaderView(){
            let effectiveHeight = kTableHeaderHeight-kTableHeaderCutAway/2
            var headerRect = CGRect(x: 0, y: -effectiveHeight, width: scrollView.bounds.width, height: kTableHeaderHeight)
            if scrollView.contentOffset.y < -effectiveHeight {
                headerRect.origin.y = scrollView.contentOffset.y
                headerRect.size.height = -scrollView.contentOffset.y + kTableHeaderCutAway/2
            }
    
            headerView.frame = headerRect
    
            let path = UIBezierPath()
            path.moveToPoint(CGPoint(x: 0, y: 0))
            path.addLineToPoint(CGPoint(x: headerRect.width, y: 0))
            path.addLineToPoint(CGPoint(x: headerRect.width, y: headerRect.height))
            path.addLineToPoint(CGPoint(x: 0, y: headerRect.height-kTableHeaderCutAway))
            headerMaskLayer?.path = path.CGPath
        }
    
    }
    
    extension UIImage {
    
        func imageWithColor(colour: UIColor) -> UIImage {
            let rect = CGRectMake(0, 0, 1, 1)
    
            // Create a 1x1 pixel content
            UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
            colour.setFill()
            UIRectFill(rect)
    
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return image
        }
    
        func imageWithAlpha(alpha: CGFloat) -> UIImage {
            UIGraphicsBeginImageContextWithOptions(size, false, scale)
            drawAtPoint(CGPointZero, blendMode: .Normal, alpha: alpha)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage
        }
    
    }
    

    我认为动画不是很流畅,在某些时候标题图像没有设置回屏幕顶部。

    有谁知道如何创建这样的navigationBar?

    非常感谢你的帮助!

1 个答案:

答案 0 :(得分:3)

这正是您想要的,它允许您创建具有灵活高度的标题栏。通常,这种UI范例用于隐藏&#34; chrome&#34;并在用户滚动时为更多内容腾出空间。

https://github.com/bryankeller/BLKFlexibleHeightBar/