当你读到苹果文档 https://developer.apple.com/reference/uikit/uivisualeffectview你可以找到:
使用 UIVisualEffectView 类时,请避免使用以下 alpha 值:
小于 1。
事实上,您还应该收到警告:
[Warning] <UIVisualEffectView 0x7af7a3b0> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.
P.S.: 请注意,我的意思是您可以更改视觉效果的 Alpha,但视图可能会显示为部分透明而不是模糊。
如果你不相信这个文档,你可以在一个空白项目中测试我下面的小例子,你可以看到,如果你改变 alpha 值,你的效果将停止正常工作:
(您可以在我的下面找到所有项目GitHUB存储库here https://github.com/aornano/UIVisualEffectView-in-a-NavigationBar-changing-alpha-)
在空白项目中准备一个连接到 viewController 的 navigationController,如下所示:
将通用图像与UIImageView
到 viewController 的视图,如下图所示:
class ViewController: UIViewController {
var blurView: UIVisualEffectView!
var effect: UIBlurEffectStyle = .light
var blurEffect : UIBlurEffect!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// This code make more transparent our navigation
if let navigationBar = navigationController?.navigationBar {
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.tintColor = .white
let textAttributes = [NSForegroundColorAttributeName:UIColor.white]
navigationBar.titleTextAttributes = textAttributes
navigationBar.shadowImage = UIImage()
navigationBar.backgroundColor = UIColor(red: 0.0, green: 0.3, blue: 0.5, alpha: 0.3)
navigationBar.isTranslucent = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 10.0, *) {
effect = .prominent
} else {
// Fallback on earlier versions
}
if let navigationBar = navigationController?.navigationBar {
let noEffectView = UIVisualEffectView.init(frame: navigationBar.bounds)
self.blurEffect = UIBlurEffect(style: effect)
self.blurView = noEffectView
navigationBar.addSubview(self.blurView)
// This line below to don't blur buttons and title
navigationBar.sendSubview(toBack: self.blurView)
// Apply the effect:
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.applyBlur), userInfo: nil, repeats: false)
}
}
func applyBlur() {
print("Apply the blur effect..")
UIView.animate(withDuration: 10.2, animations: {
self.blurView.effect = self.blurEffect
}, completion:{ (finished: Bool) in
// Make test with a simple timer:
Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(self.changeAlpha), userInfo: nil, repeats: true)
})
}
func changeAlpha() {
let startNum:CGFloat = 0.0; let stopNum:CGFloat = 200.0
let randomNum = CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(startNum - stopNum) + min(startNum, stopNum)
var alpha = (randomNum / 200)
alpha = alpha > 1.0 ? 1.0 : alpha
print("we change alpha to : \(alpha)")
self.blurView.alpha = alpha
}
}
带有模糊效果的输出:
alpha 变化期间的输出:
一个办法:
可能您不想更改 alpha 值,而是更改滚动期间的模糊效果量所以解决方案可能是使用新的fractionComplete
of UIViewPropertyAnimator
财产只能从iOS 10.0(如建议的this https://stackoverflow.com/a/42608071/1894067其他答案)
import UIKit
@available(iOS 10.0, *)
class ViewController: UIViewController {
var blurView: UIVisualEffectView!
var effect: UIBlurEffectStyle = .light
var blurEffect : UIBlurEffect!
var animator: UIViewPropertyAnimator!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// This code make more transparent our navigation
if let navigationBar = navigationController?.navigationBar {
navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBar.tintColor = .white
let textAttributes = [NSForegroundColorAttributeName:UIColor.white]
navigationBar.titleTextAttributes = textAttributes
navigationBar.shadowImage = UIImage()
navigationBar.backgroundColor = UIColor(red: 0.0, green: 0.3, blue: 0.5, alpha: 0.3)
navigationBar.isTranslucent = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
effect = .prominent
if let navigationBar = navigationController?.navigationBar {
let noEffectView = UIVisualEffectView.init(frame: navigationBar.bounds)
self.blurEffect = UIBlurEffect(style: effect)
self.blurView = noEffectView
navigationBar.addSubview(self.blurView)
// This line below to don't blur buttons and title
navigationBar.sendSubview(toBack: self.blurView)
// Apply the effect:
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.applyBlur), userInfo: nil, repeats: false)
}
}
func applyBlur() {
print("Apply the blur effect..")
animator = UIViewPropertyAnimator(duration: 0.5, curve: .linear)
self.blurView.effect = self.blurEffect
animator.addAnimations {
self.blurView.effect = nil
}
Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(self.changeBlurFraction), userInfo: nil, repeats: true)
}
func changeBlurFraction() {
let startNum:CGFloat = 0.0; let stopNum:CGFloat = 200.0
let randomNum = CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(startNum - stopNum) + min(startNum, stopNum)
var blurFraction = (randomNum / 200)
blurFraction = blurFraction > 1.0 ? 1.0 : blurFraction
print("we change the blur fraction to : \(blurFraction)")
animator.fractionComplete = blurFraction
}
}
正如您所看到的,这改变了模糊效果而不是 Alpha,并且每次触发计时器时,您都可以看到导航栏的不同模糊值。
诀窍是应用模糊效果并添加一个新的动画以将效果报告为零,但每次都使用新的“分数”将动画更改为模糊的确切值。
Output: