导航栏中的转换与 IOS 音乐应用相同
Transitions in navigation bar same as IOS Music App
这个导航栏的过渡效果怎么弄?? (与苹果的音乐应用相同)
IMAGE1
在此图中,我们有一个完全透明的导航栏,只有导航栏按钮可见
IMAGE2
随着你向上滚动条变得模糊
同样,当你向下滚动时,条变得不那么模糊
IMAGE3
并且在某个点之后导航栏变成默认的导航栏,里面有Title
任何人都可以指导我如何实现上述过渡效果
我现在拥有的是
func addBlurEffect() {
// Add blur view
var bounds = self.navigationController?.navigationBar.bounds as CGRect!
visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Dark))
bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
visualEffectView.frame = bounds
visualEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.navigationController?.navigationBar.addSubview(visualEffectView)
self.navigationController?.navigationBar.sendSubviewToBack(visualEffectView)
}
我可以模糊我的酒吧,但我希望它模糊它作为 iOS
中的音乐应用程序
关键是使用滚动偏移来设置 visualEffectView.
的 alpha 然后当图像是 navigationBar 从完全离开屏幕的高度时,您从透明导航栏切换到正常半透明一。我创建了一个视图控制器 class,可以使用 UIScrollView
执行此操作,但同样的原则适用于 UITableView
或 UICollectionView
。
import UIKit
class NavigationBlurViewController: UIViewController, UIScrollViewDelegate {
// Might not want to hard code the height of the navBar but YOLO
let navBarHeight: CGFloat = 66.0
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
let contentView = UIView()
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = UIImage(named: "Swift")
imageView.clipsToBounds = true
imageView.contentMode = .ScaleAspectFill
return imageView
}()
lazy var visualEffectView: UIVisualEffectView = {
let blurEffect = UIBlurEffect(style: .Light)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.alpha = 0.0
return visualEffectView
}()
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addSubview(self.scrollView)
self.scrollView.addSubview(self.contentView)
self.contentView.addSubview(self.imageView)
self.contentView.addSubview(self.visualEffectView)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.tintColor = UIColor.blackColor()
}
override func updateViewConstraints()
{
super.updateViewConstraints()
self.scrollView.topAnchor.constraintEqualToAnchor(self.view.topAnchor).active = true
self.scrollView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor).active = true
self.scrollView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor).active = true
self.scrollView.bottomAnchor.constraintEqualToAnchor(self.view.bottomAnchor).active = true
self.imageView.topAnchor.constraintEqualToAnchor(self.contentView.topAnchor, constant: -navBarHeight).active = true
self.imageView.leadingAnchor.constraintEqualToAnchor(self.contentView.leadingAnchor).active = true
self.imageView.trailingAnchor.constraintEqualToAnchor(self.contentView.trailingAnchor).active = true
// 150.0 or however tall you want your image
self.imageView.heightAnchor.constraintEqualToConstant(150.0 + navBarHeight).active = true
self.visualEffectView.centerXAnchor.constraintEqualToAnchor(self.imageView.centerXAnchor).active = true
self.visualEffectView.centerYAnchor.constraintEqualToAnchor(self.imageView.centerYAnchor).active = true
self.visualEffectView.widthAnchor.constraintEqualToAnchor(self.imageView.widthAnchor).active = true
self.visualEffectView.heightAnchor.constraintEqualToAnchor(self.imageView.heightAnchor).active = true
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
scrollView.delegate = self
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
// Height just 1000 for example
self.scrollView.contentSize = CGSize(width: self.view.bounds.width, height: 1000.0)
self.contentView.frame = CGRect(x: 0.0, y: 0.0, width: self.scrollView.contentSize.width, height: self.scrollView.contentSize.height)
}
func scrollViewDidScroll(scrollView: UIScrollView)
{
// Decrease size of denominator to make it blur faster
self.visualEffectView.alpha = scrollView.contentOffset.y * 1.0 / (self.imageView.frame.height - (2.0 * navBarHeight))
if scrollView.contentOffset.y > (self.imageView.frame.height - (2.0 * navBarHeight)) && self.navigationController?.navigationBar.backgroundImageForBarMetrics(UIBarMetrics.Default) != nil
{
self.navigationController?.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = nil
}
else if scrollView.contentOffset.y < (self.imageView.frame.height - (2.0 * navBarHeight)) && self.navigationController?.navigationBar.backgroundImageForBarMetrics(UIBarMetrics.Default) == nil
{
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
}
}
}
大部分效果逻辑在scrollViewDidScroll
中。您从图像视图上的效果视图开始,但随着 y 偏移量的增加,您会增加不透明度,因此完全透明,反之亦然。一旦你到达一个点,只有导航栏的高度留给图像切换到 UINavigationBar
的默认背景,否则使用 UIImage()
使其透明。
结果是:
或 gif here
显然,Apple Music 会进行其他图像处理以获得柔和的晕影,您可能需要尝试使用这些值才能按照您想要的方式获得它,但这应该可以让您完成大部分工作.
这个导航栏的过渡效果怎么弄?? (与苹果的音乐应用相同)
IMAGE1
在此图中,我们有一个完全透明的导航栏,只有导航栏按钮可见
IMAGE2
随着你向上滚动条变得模糊
同样,当你向下滚动时,条变得不那么模糊
IMAGE3
并且在某个点之后导航栏变成默认的导航栏,里面有Title
任何人都可以指导我如何实现上述过渡效果
我现在拥有的是
func addBlurEffect() {
// Add blur view
var bounds = self.navigationController?.navigationBar.bounds as CGRect!
visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Dark))
bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
visualEffectView.frame = bounds
visualEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.navigationController?.navigationBar.addSubview(visualEffectView)
self.navigationController?.navigationBar.sendSubviewToBack(visualEffectView)
}
我可以模糊我的酒吧,但我希望它模糊它作为 iOS
中的音乐应用程序关键是使用滚动偏移来设置 visualEffectView.
的 alpha 然后当图像是 navigationBar 从完全离开屏幕的高度时,您从透明导航栏切换到正常半透明一。我创建了一个视图控制器 class,可以使用 UIScrollView
执行此操作,但同样的原则适用于 UITableView
或 UICollectionView
。
import UIKit
class NavigationBlurViewController: UIViewController, UIScrollViewDelegate {
// Might not want to hard code the height of the navBar but YOLO
let navBarHeight: CGFloat = 66.0
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
return scrollView
}()
let contentView = UIView()
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = UIImage(named: "Swift")
imageView.clipsToBounds = true
imageView.contentMode = .ScaleAspectFill
return imageView
}()
lazy var visualEffectView: UIVisualEffectView = {
let blurEffect = UIBlurEffect(style: .Light)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.alpha = 0.0
return visualEffectView
}()
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addSubview(self.scrollView)
self.scrollView.addSubview(self.contentView)
self.contentView.addSubview(self.imageView)
self.contentView.addSubview(self.visualEffectView)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.tintColor = UIColor.blackColor()
}
override func updateViewConstraints()
{
super.updateViewConstraints()
self.scrollView.topAnchor.constraintEqualToAnchor(self.view.topAnchor).active = true
self.scrollView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor).active = true
self.scrollView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor).active = true
self.scrollView.bottomAnchor.constraintEqualToAnchor(self.view.bottomAnchor).active = true
self.imageView.topAnchor.constraintEqualToAnchor(self.contentView.topAnchor, constant: -navBarHeight).active = true
self.imageView.leadingAnchor.constraintEqualToAnchor(self.contentView.leadingAnchor).active = true
self.imageView.trailingAnchor.constraintEqualToAnchor(self.contentView.trailingAnchor).active = true
// 150.0 or however tall you want your image
self.imageView.heightAnchor.constraintEqualToConstant(150.0 + navBarHeight).active = true
self.visualEffectView.centerXAnchor.constraintEqualToAnchor(self.imageView.centerXAnchor).active = true
self.visualEffectView.centerYAnchor.constraintEqualToAnchor(self.imageView.centerYAnchor).active = true
self.visualEffectView.widthAnchor.constraintEqualToAnchor(self.imageView.widthAnchor).active = true
self.visualEffectView.heightAnchor.constraintEqualToAnchor(self.imageView.heightAnchor).active = true
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
scrollView.delegate = self
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
// Height just 1000 for example
self.scrollView.contentSize = CGSize(width: self.view.bounds.width, height: 1000.0)
self.contentView.frame = CGRect(x: 0.0, y: 0.0, width: self.scrollView.contentSize.width, height: self.scrollView.contentSize.height)
}
func scrollViewDidScroll(scrollView: UIScrollView)
{
// Decrease size of denominator to make it blur faster
self.visualEffectView.alpha = scrollView.contentOffset.y * 1.0 / (self.imageView.frame.height - (2.0 * navBarHeight))
if scrollView.contentOffset.y > (self.imageView.frame.height - (2.0 * navBarHeight)) && self.navigationController?.navigationBar.backgroundImageForBarMetrics(UIBarMetrics.Default) != nil
{
self.navigationController?.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = nil
}
else if scrollView.contentOffset.y < (self.imageView.frame.height - (2.0 * navBarHeight)) && self.navigationController?.navigationBar.backgroundImageForBarMetrics(UIBarMetrics.Default) == nil
{
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage()
}
}
}
大部分效果逻辑在scrollViewDidScroll
中。您从图像视图上的效果视图开始,但随着 y 偏移量的增加,您会增加不透明度,因此完全透明,反之亦然。一旦你到达一个点,只有导航栏的高度留给图像切换到 UINavigationBar
的默认背景,否则使用 UIImage()
使其透明。
结果是:
或 gif here
显然,Apple Music 会进行其他图像处理以获得柔和的晕影,您可能需要尝试使用这些值才能按照您想要的方式获得它,但这应该可以让您完成大部分工作.