2015-01-13 37 views
15

我在CGAffineTransform縮放和平移的問題上掙扎,當我在已經有轉換的視圖上的動畫塊中設置轉換時,視圖在動畫之前跳轉了一下。CGAffineTransform縮放和平移 - 在動畫之前跳轉

實施例:

// somewhere in view did load or during initialization 
var view = UIView() 
view.frame = CGRectMake(0,0,100,100) 
var scale = CGAffineTransformMakeScale(0.8,0.8) 
var translation = CGAffineTransformMakeTranslation(100,100) 
var concat = CGAffineTransformConcat(translation, scale) 
view.transform = transform 

// called sometime later 
func buttonPressed() { 
    var secondScale = CGAffineTransformMakeScale(0.6,0.6) 
    var secondTranslation = CGAffineTransformMakeTranslation(150,300) 
    var secondConcat = CGAffineTransformConcat(secondTranslation, secondScale) 
    UIView.animateWithDuration(0.5, animations: {() -> Void in 
     view.transform = secondConcat 
    }) 

} 

現在,當buttonPressed()被調用視圖跳轉到頂部左約10個像素開始進行動畫之前。我只是目睹了一個concat轉換的問題,只使用了一個轉換轉換工作正常。

編輯:既然我已經做了很多的研究關於此事,我認爲我應該指出,這個問題無論自動佈局是否被開啓

+0

如果您使用'CGAffineTransformTranslate(secondScale,150,300)',該怎麼辦? –

+0

結果完全一樣 – matteok

+0

「有點跳躍」是什麼意思?它是否會返回到身份轉換?它是從跳躍動畫到'secondConcat'還是跳轉,返回到concat,_then_動畫到'secondConcat'? –

回答

25

我遇到了同樣的問題,但無法找到問題的確切來源。跳轉似乎只出現在非常特定的條件下:如果視圖從變換t1動畫到變換t2,並且兩個變換都是比例和翻譯的組合(這正是您的情況)。鑑於下面的解決方法,這對我來說沒有意義,我認爲這是Core Animation中的一個錯誤。我試過用CATransform3D代替CGAffineTransform

舊代碼:

var transform = CGAffineTransformIdentity 
transform = CGAffineTransformScale(transform, 1.1, 1.1) 
transform = CGAffineTransformTranslate(transform, 10, 10) 
view.layer.setAffineTransform(transform) 

新代碼:

var transform = CATransform3DIdentity 
transform = CATransform3DScale(transform, 1.1, 1.1, 1.0) 
transform = CATransform3DTranslate(transform, 10, 10, 0) 
view.layer.transform = transform 

新代碼應相當於舊(第四個參數設置爲1.00,使沒有脫屑/翻譯在z方向),並且實際上它顯示相同的跳躍。然而,這裏來的黑魔法:在大規模改造,z參數有什麼不同從1.0改變,像這樣:

transform = CATransform3DScale(transform, 1.1, 1.1, 1.01) 

此參數應該沒有影響,但現在跳走了。

+0

我認爲這個答案沒有得到足夠的學分......我一直在編碼的日子,無法解決這個問題。 – farzadshbfn

0

相反CGAffineTransformMakeScale()和CGAffineTransformMakeTranslation的出現() ,它基於CGAffineTransformIdentity(基本上沒有變換)創建一個變換,您希望使用CGAffineTransformScale()和CGAffineTransformTranslate()(基於現有變換開始)基於視圖的當前變換進行縮放和平移。

+0

我實際上需要在動畫期間設置一個絕對變換,這意味着我不想添加到現有的變換中,而是將其替換爲動畫 – matteok

+1

另外我剛剛嘗試使用CGAffineTransformTranslate而不是CGAffineTransformMakeTranslate,問題保持不變。 – matteok

1

問題的根源在於對變換缺乏透視信息。

您可以添加角度信息修改你的3D的m34屬性變換

var transform = CATransform3DIdentity 
transform.m34 = 1.0/200 //your own perspective value here 
transform = CATransform3DScale(transform, 1.1, 1.1, 1.0) 
transform = CATransform3DTranslate(transform, 10, 10, 0) 
view.layer.transform = transform 
+0

你能解釋一下更多,也是爲什麼[這個](http://stackoverflow.com/a/33465048/1971013)'神奇'的作品? –

2

看起來像蘋果的UIView動畫內部錯誤。當蘋果插值兩個值之間CGAffineTransform變化來製作動畫它應該做以下步驟:

  • 提取平移,縮放和旋轉
  • 插值提取值的形式開始到結束
  • 裝配CGAffineTransform每個插值步驟

組裝應按照以下順序:

  • 翻譯
  • 縮放
  • 旋轉

不過貌似蘋果縮放和旋轉之後使譯文。這個bug應該由Apple修復。