你如何以编程方式更改NavigationBar中的UIVisualEffectView的alpha?

时间:2017-03-29 17:02:20

标签: swift uikit

我有一个滚动视图,用于控制其他元素的alpha值,具体取决于用户滚动视图的距离。

首先,我设置了模糊视图。 Alpha似乎没有采取,首先

var effect: UIBlurEffectStyle = .light
if #available(iOS 10.0, *) {
    effect = .prominent
}
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: effect))
blurView.alpha = 0
if let navigationBar = navigationController?.navigationBar {
    blurView.frame = navigationBar.bounds
}
self.blurView = blurView

navbar

然后在我的UIScrollViewDelegate

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        var alpha = (scrollView.contentOffset.y / 200)
        alpha = alpha > 1.0 ? 1.0 : alpha

        blurView?.alpha = alpha
}

这似乎也不起作用。

关于如何实现这种效果的任何建议?谢谢!

3 个答案:

答案 0 :(得分:2)

当您阅读Apple documentation时,您可以找到:

  

使用UIVisualEffectView类时,请避免使用alpha值   不到1个。

enter image description here

实际上你也应该收到警告:

[Warning] <UIVisualEffectView 0x7af7a3b0> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.

PS: 注意,我的意思是你可以改变视觉效果的alpha,但视图可能看起来只是部分透明而不是模糊。 < / p>

如果您不相信本文档,可以将下面的小示例测试为空白项目,您可以看到,如果更改了alpha值,效果将停止正常工作:

(您可以在我的 GitHUB 存储库here中找到以下所有项目)

在空白项目中准备一个连接到viewController的navigationController,如下所示:

enter image description here

将带有UIImageView的通用图像放到viewController的视图中,如下图所示:

enter image description here

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
    }
}

带模糊效果的输出:

enter image description here

Alpha更改期间的输出:

enter image description here

解决方案:

可能您不想更改alpha值但在滚动期间更改模糊效果,因此解决方案可能是使用{{1}的新fractionComplete }}属性仅可从 iOS 10.0 获得(如this其他SO回答中所述)

UIViewPropertyAnimator

正如您所看到的,这会改变模糊效果而不是alpha,每次定时器被触发时,您都可以在导航栏中看到不同的模糊值。

诀窍是应用模糊效果并添加一个新动画来将效果报告为零,但每次使用新的&#34;分数&#34;将动画更改为精确的模糊值。

<强>输出:

enter image description here

答案 1 :(得分:1)

Swift 5.0。只需使用以下代码:

navigationController?.navigationBar.isTranslucent = false

它以纯色(alpha = 1)更改“ 0.85 alpha效果”。

答案 2 :(得分:0)

由于Apple对实施的内部更改,从iOS 10开始,UIVisualEffectView的Alpha混合与图层屏蔽一样被打破。

我建议使用UIView​Property​Animator对象从实际效果(在您的情况下为.prominent)过渡到nil,然后手动将fractionComplete设置为是alpha值。它会为您提供更好的效果,并允许您以交互方式更改效果。