swift - CGAffineTransform 弄乱了 ViewFrame
问题描述
我有一个UIViewControllerAnimatedTransitioning
其中一个动画是使用比例尺CGAffineTransform
toView.frame.origin.y = containerView.frame.size.height - toView.frame.height
fromView.transform = CGAffineTransform(scaleX: 0.96, y: 0.94)
fromView.frame = fromView.frame.offsetBy(dx: 0, dy: self.topOffset)
这让我的框架从(0.0, 0.0, 375.0, 667.0)
到(7.5, 20.00999999999999, 360.0, 626.98)
,并在回来的路上:
toView.transform = CGAffineTransform.identity
toView.frame = toView.frame.offsetBy(dx: 0, dy: -self.topOffset)
fromView.frame.origin.y = containerView.frame.size.height
问题是:而不是框架回到原来的状态,它搞砸了,现在我得到了:0.0, -5.684341886080802e-14, 375.0, 667.0000000000001)
,主要问题当然是 y 定位。
请注意 self.topOffset 的值为 0,我尝试删除此行,但没有任何结果。
第fromView
一个片段的第一个片段是toView
第二个片段的。
如果要检查该函数的完整代码:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromViewController = transitionContext.viewController(forKey: .from),
let toViewController = transitionContext.viewController(forKey: .to),
let toView = toViewController.view,
let fromView = fromViewController.view,
let containerView = containerView else { return }
let isPresenting = fromViewController == presentingViewController
if isPresenting {
toView.frame.origin.y = fromView.frame.size.height
}
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 0,
options: .curveEaseInOut,
animations: {
if isPresenting {
toView.frame.origin.y = containerView.frame.size.height - toView.frame.height
fromView.transform = CGAffineTransform(scaleX: 0.96, y: 0.94)
fromView.frame = fromView.frame.offsetBy(dx: 0, dy: self.topOffset)
}
else {
toView.transform = CGAffineTransform.identity
toView.frame = toView.frame.offsetBy(dx: 0, dy: -self.topOffset)
fromView.frame.origin.y = containerView.frame.size.height
}
}) { (finished) in
if finished {
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
顺便说一句,将初始值保留在变量上并在之后设置它可以解决问题,但这似乎是一种解决方法而不是解决方案。我想了解它为什么会发生,以及是否有更好的方法来做到这一点。
解决方案
这是我认为可能是错误的。从UIView 框架上的文档,
如果变换属性不是恒等变换,则该属性的值是未定义的,因此应该被忽略。
你不应该在设置转换后使用 frame 属性。相反,如文档中所述,
对此属性的更改可以设置动画。但是,如果 transform 属性包含非恒等变换,则 frame 属性的值是未定义的,不应修改。在这种情况下,使用 center 属性重新定位视图并使用 bounds 属性调整大小。
所以
fromView.frame = fromView.frame.offsetBy(dx: 0, dy: self.topOffset)
需要修改为
fromView.center = fromView.frame.center + self.topOffset
fromView.frame = fromView.frame.bounds
但我认为我们不需要修改 toView 代码,因为我们在设置框架之前将 transform 设置为 Identity。
根据上面所说,解决问题的方法是修改第一个块:
toView.frame.origin.y = containerView.frame.size.height - toView.frame.height
fromView.transform = CGAffineTransform(scaleX: 0.96, y: 0.94)
fromView.frame = fromView.frame.offsetBy(dx: 0, dy: self.topOffset)
至
toView.frame.origin.y = containerView.frame.size.height - toView.frame.height
fromView.frame = fromView.frame.offsetBy(dx: 0, dy: self.topOffset)
fromView.transform = CGAffineTransform(scaleX: 0.96, y: 0.94)
基本上在应用变换之前进行帧重新定位。
推荐阅读
- reactjs - react-table 不断重新渲染未更改的单元格
- node.js - request.pipe() 允许失败的请求
- r - 在应用族函数调用的函数中使用 mutate
- angular - 如何保留标签之间登录的用户会话?
- mongodb - 不同类型的 MongoDB 大小(以字节为单位)
- c# - 如何在 C# 中序列化/反序列化对象矩阵到/从 xml?
- mongodb - MongoDB随着时间的推移降低写入性能
- python - 在python WindowsError: [错误3] 系统找不到指定的路径:'F:/Dataset\\*.*'
- python - Python - 在没有数据连接的情况下保存 Excel 电子表格
- python-3.x - 我使用 TensoFlow 2.0 和 python3.6 以 99.68% 的准确率训练 MNIST 数据集,但它预测数字错误