我正在以模糊背景效果模式呈现视图控制器。 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
答案 0 :(得分:8)
您需要创建一个新的UIViewControllerAnimatedTransitioning
。
然后在animateTransition(using transitionContext: UIViewControllerContextTransitioning)
中,您需要为动画编码。
现在,在iOS 10中,您可以使用UIViewPropertyAnimator
为BlurRadius
的{{1}}设置动画。
这里有一个使用示例: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中那么好,倒退,但稍微好一些。
显示没有动画的视图控制器:
presentViewController(modalVC, animated: false, completion: nil)
从头开始隐藏您的观点:
override func viewDidLoad() {
super.viewDidLoad()
view.alpha = 0
}
手动应用动画:
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