我正在以模糊背景效果模式呈现视图控制器. 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动画完成后,背景颜色将更改为实际的模糊效果背景.任何想法为什么会这样?
还试图在viewDidLoad()的开头和结尾为模态视图控制器添加layoutIfNeeded(),没有任何运气.我正在使用swift 2.3
解决方法
嗨,
您需要创建一个新的UIViewControllerAnimatedTransitioning.
然后在animateTransition中(使用transitionContext:UIViewControllerContextTransitioning),您需要编写动画代码.
现在在iOS 10中,您可以使用UIViewPropertyAnimator为UIVisualBlurEffect的BlurRadius设置动画.
这里有一个用法示例:https://github.com/PierrePerrin/PPBlurModalPresentation
第一
您需要创建模糊转换
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,animations: { self.destinationView.alpha = 1.0 self.blurView.effect = nil },completion: { (position) in completion() }) } }
然后
您需要在ViewController中设置转换委派:
import UIKit class ViewController: UIViewController,UIViewControllerTransitioningDelegate { let blurModalPresentation = BlurModalPresentation() override func viewDidLoad() { super.viewDidLoad() } func showVC(){ let str = self.storyboard! let vc = str.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") vc.transitioningDelegate = self self.present(vc,completion: nil) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) } func animationController(forPresented presented: UIViewController,presenting: UIViewController,source: UIViewController) -> UIViewControllerAnimatedTransitioning?{ return blurModalPresentation } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{ return blurModalPresentation } }