使用 CATransition self.dismiss 时隐藏黑色渐变
Hide a black fade when self.dismiss with CATransition
我想让我的 viewController 变成带动画的旧 viewController。但是当我使用 CATransition 时,我的 viewController 和旧的 viewController 变黑了。有什么办法让它不掉色吗?
let transition = CATransition()
transition.duration = 1.0
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window!.layer.add(transition, forKey: kCATransition)
self.dismiss(animated: false, completion: nil)
详细了解转换 here 并尝试修改可用参数以获得所需的效果。
有关转换的良好未记录信息 available here。
如果您想要一些好的解决方案 - 您应该为您的屏幕准备自定义过渡 - 检查此 WWDC video
另一种快速(但不是最佳)解决方案可能是在 viewController 中手动控制 presentation/dismiss:
import UIKit
final class AnimatableViewController: UIViewController {
private var panStartLocation:CGPoint = CGPoint.zero
private var panPrevLocation:CGPoint = CGPoint.zero
var onClose:(()->())?
// MARK: - LifeCycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
openAnimation()
}
// MARK: - IBAction
@objc private func closeButtonAction(_ sender: UIButton) {
dismiss(animated: true, completion: { [weak self] in
self?.onClose?()
})
}
// MARK: - Gestures
@IBAction private func didDetectPan(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began:
panStartLocation = sender.location(in: navigationController?.view)
panPrevLocation = panStartLocation
case .cancelled, .ended:
finishAnimation()
case .changed:
let newPoint:CGPoint = sender.location(in: navigationController?.view)
let dy:CGFloat = newPoint.y - panPrevLocation.y
var newPosition:CGPoint = view.center
if (newPoint.y - panStartLocation.y > 0) {
newPosition.y += dy
} else {
newPosition.y = self.view.bounds.height / 2
}
view.center = newPosition
panPrevLocation = newPoint
default:
break
}
}
//MARK: Animation
private func finishAnimation() {
let center:CGPoint = view.center
if (center.y > self.view.bounds.height / 2 * 1.35) {
closeAnimation()
} else {
openAnimation()
}
}
private func closeAnimation() {
let fullAnimTime:CGFloat = 0.5
let endPoint:CGPoint = CGPoint(x:view.center.x, y:view.bounds.height / 2 * 3)
let animTime:CGFloat = ((endPoint.y - view.center.y) / self.view.bounds.height) * fullAnimTime
UIView.animate(withDuration: TimeInterval(animTime), animations: { [weak self] in
self?.view.center = endPoint
}, completion: { [weak self] _ in
self?.dismiss(animated: false, completion: {
self?.onClose?()
})
})
}
private func openAnimation() {
let fullAnimTime:CGFloat = 0.5
let endPoint:CGPoint = CGPoint(x: view.center.x, y:self.view.bounds.height / 2)
let animTime:CGFloat = ((view.center.y - endPoint.y) / (self.view.bounds.height / 2)) * fullAnimTime
UIView.animate(withDuration: TimeInterval(animTime)) { [weak self] in
self?.view.center = endPoint
}
}
}
extension AnimatableViewController: UIGestureRecognizerDelegate {
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer is UIPanGestureRecognizer {
return false
}
return true
}
}
在情节提要中,不要忘记将 segue 参数设置为:
并将 panGesture 添加到您的根视图或将任何其他平移手势添加到最顶部的视图,可用于平移 - 在我的例子中 - 我只是将平移添加到 rootView:
结果:
我想让我的 viewController 变成带动画的旧 viewController。但是当我使用 CATransition 时,我的 viewController 和旧的 viewController 变黑了。有什么办法让它不掉色吗?
let transition = CATransition()
transition.duration = 1.0
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
view.window!.layer.add(transition, forKey: kCATransition)
self.dismiss(animated: false, completion: nil)
详细了解转换 here 并尝试修改可用参数以获得所需的效果。
有关转换的良好未记录信息 available here。
如果您想要一些好的解决方案 - 您应该为您的屏幕准备自定义过渡 - 检查此 WWDC video
另一种快速(但不是最佳)解决方案可能是在 viewController 中手动控制 presentation/dismiss:
import UIKit
final class AnimatableViewController: UIViewController {
private var panStartLocation:CGPoint = CGPoint.zero
private var panPrevLocation:CGPoint = CGPoint.zero
var onClose:(()->())?
// MARK: - LifeCycle
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
openAnimation()
}
// MARK: - IBAction
@objc private func closeButtonAction(_ sender: UIButton) {
dismiss(animated: true, completion: { [weak self] in
self?.onClose?()
})
}
// MARK: - Gestures
@IBAction private func didDetectPan(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began:
panStartLocation = sender.location(in: navigationController?.view)
panPrevLocation = panStartLocation
case .cancelled, .ended:
finishAnimation()
case .changed:
let newPoint:CGPoint = sender.location(in: navigationController?.view)
let dy:CGFloat = newPoint.y - panPrevLocation.y
var newPosition:CGPoint = view.center
if (newPoint.y - panStartLocation.y > 0) {
newPosition.y += dy
} else {
newPosition.y = self.view.bounds.height / 2
}
view.center = newPosition
panPrevLocation = newPoint
default:
break
}
}
//MARK: Animation
private func finishAnimation() {
let center:CGPoint = view.center
if (center.y > self.view.bounds.height / 2 * 1.35) {
closeAnimation()
} else {
openAnimation()
}
}
private func closeAnimation() {
let fullAnimTime:CGFloat = 0.5
let endPoint:CGPoint = CGPoint(x:view.center.x, y:view.bounds.height / 2 * 3)
let animTime:CGFloat = ((endPoint.y - view.center.y) / self.view.bounds.height) * fullAnimTime
UIView.animate(withDuration: TimeInterval(animTime), animations: { [weak self] in
self?.view.center = endPoint
}, completion: { [weak self] _ in
self?.dismiss(animated: false, completion: {
self?.onClose?()
})
})
}
private func openAnimation() {
let fullAnimTime:CGFloat = 0.5
let endPoint:CGPoint = CGPoint(x: view.center.x, y:self.view.bounds.height / 2)
let animTime:CGFloat = ((view.center.y - endPoint.y) / (self.view.bounds.height / 2)) * fullAnimTime
UIView.animate(withDuration: TimeInterval(animTime)) { [weak self] in
self?.view.center = endPoint
}
}
}
extension AnimatableViewController: UIGestureRecognizerDelegate {
// MARK: - UIGestureRecognizerDelegate
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer is UIPanGestureRecognizer {
return false
}
return true
}
}
在情节提要中,不要忘记将 segue 参数设置为:
并将 panGesture 添加到您的根视图或将任何其他平移手势添加到最顶部的视图,可用于平移 - 在我的例子中 - 我只是将平移添加到 rootView:
结果: