ios - 自定义 UIViewController 动画问题
问题描述
UIViewController
我为with创建了一个简单的自定义过渡动画UIViewControllerAnimatedTransitioning
。一切正常,但是当目标视图出现时,内容从右下角开始出现,当视图消失时,内容从左上角消失。我附上了 gif 示例。这是我的代码:
CustomViewAnimator.swift
class CustomViewAnimator: NSObject, UIViewControllerAnimatedTransitioning {
private let interval = 0.5
var forward = false
var originFrame: CGRect = .zero
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return interval
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: .to) else {return}
guard let fromView = transitionContext.view(forKey: .from) else {return}
let destinationView = forward ? toView : fromView
destinationView.alpha = forward ? 0 : 1
forward ? containerView.addSubview(toView) : containerView.insertSubview(toView, belowSubview: fromView)
forward ? (destinationView.frame = originFrame) : (destinationView.frame = fromView.frame)
UIView.animate(withDuration: interval, animations: {
self.forward ? (destinationView.frame = fromView.frame) : (destinationView.frame = self.originFrame)
destinationView.alpha = self.forward ? 1 : 0
}) { (finished) in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
MainViewController.self
class MainViewController: UIViewController {
private var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
@objc private func openView() {
let viewController = TargetViewController()
viewController.transitioningDelegate = self
navigationController?.pushViewController(viewController, animated: true)
}
}
extension MainViewController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.originFrame = button.frame
animator.forward = (operation == .push)
return animator
}
}
extension MainViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.forward = true
return animator
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.forward = false
return animator
}
}
TargetViewController.swift
class TargetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
}
extension TargetViewController {
fileprivate func setup() {
view.backgroundColor = .orange
navigationItem.title = "Target view"
let label: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello from target view :)"
label.textColor = .white
label.font = UIFont.boldSystemFont(ofSize: 18)
return label
}()
view.addSubview(label)
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
谁能说我如何解决这个问题,所以 TargetViewController 中的标签(或任何其他内容)保持固定在他们的位置上?
解决方案
我同意其他答案的讨论。我的建议是不要为 UIView 的框架设置动画,您可以为目标视图的掩码设置动画,如下所示。应该是操作者真正想要的效果。
粗体部分是与原帖的区别。
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: .to) else {return}
guard let fromView = transitionContext.view(forKey: .from) else {return}
let destinationView = forward ? toView : fromView
destinationView.alpha = forward ? 0 : 1
让 maskView = UIView.init(frame: forward ? originFrame : fromView.frame)
maskView.backgroundColor = UIColor.white
destinationView.mask = maskView
forward ? containerView.addSubview(toView) : containerView.insertSubview(toView, belowSubview: fromView)
forward ? (destinationView.frame = toView.frame) : (destinationView.frame = fromView.frame)
UIView.animate(withDuration: interval, animations: {
自我转发?(destinationView.mask?.frame = fromView.frame) : (destinationView.mask?.frame = self.originFrame)
destinationView.alpha = self.forward ? 1 : 0
}) { (finished) in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
推荐阅读
- mongodb - Mongodb 4:无法启动mongod.service:未找到单元mongod.service
- python - 调用通过 Numpy 数组迭代的恒定时间函数会导致代码非常慢
- macos - 安装时检查权限和路径错误
- kubernetes - apt-get update 卡在我的 K8s 中,无法安装任何调试工具
- c++ - 在模板实例化之前并不总是选择重载函数
- jquery - JQuery 数据表 OnClick tr td :NOT tr th
- powershell - 为什么 PowerShell 多维数组创建中的新行会改变语义?
- sql - SQLite 两个值组合唯一
- php - Outlook 中的新电子邮件挂钩
- python - 如何使用工人初始化时使用的变量启动芹菜工人