![](/img/trans.png)
[英]How to further transform/animate an already transformed/animated UIView in Swift?
[英]How to correctly animate transformations on an priorly transformed UIView
無法在已翻譯的UIView
上正確執行縮放動畫。
當視圖尚未事先移動時,為了獲得所需的結果,我先應用比例尺,然后再應用平移 。 我使用UIViewPropertyAnimator
動畫化了轉換后的UIViewPropertyAnimator
:視圖在相應移動的同時向上或向下縮放。
但是,如果在應用此動畫變換之前已將視圖從其原始位置移動(平移),則我無法獲得將視圖從其新位置移動時放大或縮小的結果。
¡ 盡管變換問題已得到充分記錄-並且在提交問題之前我已經進行了盡職調查-到目前為止,我仍未找到成功的解決方案 !
為了便於理解和解決問題,已簡化了代碼。
extension UIView {
func zoomAndMove(vector: CGPoint, scale: CGPoint){
self.transform = self.transform.concatenating(CGAffineTransform(scaleX: scale.x, y: scale.y).concatenating(CGAffineTransform(translationX: vector.x, y: vector.y))
}
func animateZoomAndMove(from origin: CGPoint, for duration: TimeInterval, cameraZoom: CGPoint, timingFunction: UITimingCurveProvider, controlPoint2: CGPoint(x: 0.8, y: 0.7)) autoplay: Bool = false) -> UIViewPropertyAnimator {
let animator = UIViewPropertyAnimator(duration: duration, timingParameters: timingFunction)
let vector = CGPoint(x: self.frame.midX - origin.x, y: self.frame.midY - origin.y)
animator.addAnimations {
self.zoomAndMove(vector: vector, scale: cameraZoom)
}
if autoplay { animator.startAnimation()}
return animator
}
}
我試圖修改我的代碼以返回一個轉換,該轉換考慮了zoomAndMove
發生之前的先前轉換:
extension UIView {
func zoomAndMove(vector: CGPoint, scale: CGPoint){
if self.transform == CGAffineTransform.identity {
self.transform = self.transform.concatenating(CGAffineTransform(scaleX: scale.x, y: scale.y).concatenating(CGAffineTransform(translationX: vector.x, y: vector.y))
} else {
let preTransform = self.transform
self.transform = CGAffineTransform(a: scale.x, b: 0, c: 0, d: scale.y, tx: vector.x + preTransform.tx, ty: vector.y + preTransform.ty)
}
}
這段代碼無法達到預期的效果 :視圖跳到一個新位置,正確縮放並“隨機”移動。
我肯定錯過了一些東西-我可能瞄准的是錯誤的最終結果矩陣-但總的來說,我目前仍處於困境。
如果有人對如何執行這樣的簡單任務(例如從已翻譯的UIView縮放和移動UIView)有所了解,我將不勝感激!
最好,
一幅圖片可能值一千個單詞,所以當我嘗試實現到目前為止提出的各種建議(特別是.scaledBy(:)
方法)時,會發生以下情況:
您會注意到最終的轉換是正確的,但動畫卻不正確。
您是否嘗試過將當前轉換分配給屬性,然后修改此復制的屬性,然后重新分配給視圖? 就像是:
let originalTransform = view.transform
let scaledTransform = originalTransform.scaledBy(x: 0.2, y: 0.2)
view.transform = scaledTransform
我使用這種方法創建了一個按鈕動畫,效果很好,但是我不確定這不是您想要的。
首先,感謝@gmogames抽出寶貴的時間提出建議。 交流思想總是有幫助的!!!
實際上,該問題與在應用新轉換之前重置視圖的anchorPoint(或中心)有關,以便動畫正確運行。 因此,使用移動后縮放視圖的簡單得多的示例,這是新方法的外觀:
extension UIView {
func scaleView(scaleFactor: CGPoint, duration: TimeInterval) {
// store the view original center
let oCenter = self.center
// get the current transformation
let cTransform = self.transform
// set the new center of the view
self.center = CGPoint(x: self.frame.midX, y: self.frame.midY)
// clears the transform matrix from potential prior translation
// Note that you need to take into account potential prior scale of the view into the translation vector!!
self.transform = self.transform.translatedBy(x: -cTransform.tx / cTransform.a, y: -cTransform.ty / cTransform.d)
// Animates the transformation
let animator = UIViewPropertyAnimator(duration: duration, timingParameters: UICubicTimingParameters(controlPoint1: CGPoint(x: 0, y: 0), controlPoint2: CGPoint(x: 1, y: 1))
animator.addAnimations {
self.transform = self.transform.scaledBy(x: scaleFactor.x, y: scaleFactor.y)
}
// resets the View to its original center and apply the transformation so that the view stays in the right end position
animator.addCompletion { (position) in
if position == UIViewAnimatingPosition.end {
self.center = oCenter
self.transform = cTransform.scaledBy(x: scaleFactor.x, y: scaleFactor.y)
}
}
animator.startAnimation()
}
}
這是動畫的結果: 移動+縮放+縮放+恢復原始
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.