呈现具有模糊效果的视图控制器

时间:2016-09-22 16:54:24

标签: ios iphone swift xcode8 uiblureffect

我正在以模糊背景效果模式呈现视图控制器。 iOS 10 / XCode 8引入了我的动画问题。这是演示代码:

let modalVC = ModalViewController(nibName: "ModalViewController", bundle: nil)
modalVC.modalTransitionStyle = .CrossDissolve
modalVC.modalPresentationStyle = .OverFullScreen
presentViewController(modalVC, animated: true, completion: nil)

在ModalViewController中的viewDidLoad()函数中添加模糊:

let blurEffect = UIBlurEffect(style: .Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

view.addSubview(blurEffectView)
view.sendSubviewToBack(blurEffectView)

ModalViewController背景清晰,我添加了一个带有黑暗模糊效果的BlurEffectView。使用上一个代码段和Interface Builder以编程方式进行尝试。

在iOS 8& 9 .CrossDissolve转换处理了“淡入淡出”,但在iOS 10(设备和模拟器)上进行测试后,视图显示为深色半透明背景颜色而非模糊。

.CrossDissolve动画完成后,背景颜色会变为实际的模糊效果背景。任何想法为什么会发生这种情况?

还尝试在layoutIfNeeded()的开头和结尾为模态视图控制器添加viewDidLoad(),但没有任何运气。我正在使用swift 2.3

3 个答案:

答案 0 :(得分:8)

嗨,

您需要创建一个新的UIViewControllerAnimatedTransitioning

然后在animateTransition(using transitionContext: UIViewControllerContextTransitioning)中,您需要为动画编码。

现在,在iOS 10中,您可以使用UIViewPropertyAnimatorBlurRadius的{​​{1}}设置动画。

结果:enter image description here

这里有一个使用示例:https://github.com/PierrePerrin/PPBlurModalPresentation

第一

您需要创建模糊过渡

UIVisualBlurEffect

然后

您需要在 class BlurModalPresentation: NSObject,UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval{ return 0.5 } //This is the blur view used for transition var blurView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.light)) var destinationView : UIView! var animator: UIViewPropertyAnimator? // This method can only be a nop if the transition is interactive and not a percentDriven interactive transition. func animateTransition(using transitionContext: UIViewControllerContextTransitioning){ let containerView = transitionContext.containerView _ = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) let toVc = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) destinationView = toVc!.view destinationView.alpha = 0.0 //Here we add the blur view and set it effect to nil blurView.effect = nil blurView.frame = containerView.bounds self.blurTransition(transitionContext) { self.unBlur(transitionContext, completion: { self.blurView.removeFromSuperview() transitionContext.completeTransition(true) }) } containerView.addSubview(toVc!.view) containerView.addSubview(blurView) } //This methods add the blur to our view and our destinationView func blurTransition(_ context : UIViewControllerContextTransitioning,completion: @escaping () -> Void){ UIViewPropertyAnimator.runningPropertyAnimator(withDuration: self.transitionDuration(using: context)/2, delay: 0, options: UIViewAnimationOptions.curveLinear, animations: { self.destinationView.alpha = 0.5 self.blurView.effect = UIBlurEffect(style: UIBlurEffectStyle.light) }, completion: { (position) in completion() }) } //This Method remove the blur view with an animation func unBlur(_ context : UIViewControllerContextTransitioning,completion: @escaping () -> Void){ UIViewPropertyAnimator.runningPropertyAnimator(withDuration: self.transitionDuration(using: context) / 2, delay:0, options: UIViewAnimationOptions.curveLinear, animations: { self.destinationView.alpha = 1.0 self.blurView.effect = nil }, completion: { (position) in completion() }) } } 中设置转换委派:

ViewController

答案 1 :(得分:1)

首先,我将此解决方案视为临时解决方法,因为我必须假设这个新引入的行为是一个错误,并将在未来的更新中修复。这使得它在动画期间而不是之后弹出模糊效果时略显不太明显。仍然不如iOS 9中那么好,倒退,但稍微好一些。

  1. 显示没有动画的视图控制器:

    presentViewController(modalVC, animated: false, completion: nil)
    
  2. 从头开始隐藏您的观点:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.alpha = 0
    }
    
  3. 手动应用动画:

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        UIView.animateWithDuration(0.25) {
            self.view.alpha = 1
        }
    }
    
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
    
        UIView.animateWithDuration(0.25) {
            self.view.alpha = 0
        }
    }
    

答案 2 :(得分:1)

唯一正确的方法是创建自定义模态转换和动画效果属性。见https://stackoverflow.com/a/39709740