最近項目中有個繞y軸左右擺動UIView的需求。首先想到了使用CATransform3D來做旋轉。但是使用過程中碰到了如下兩個問題。
問題1:旋轉之後,目標View只能看到一半的UI,比如繞y軸旋轉只能看到左半邊或者右半邊。
問題2:擺動的動畫,給人感覺總是向一邊擺動(一直向左邊或者右邊)代碼如下:
CATransform3D rotationTransform = CATransform3DIdentity;
rotationTransform = CATransform3DRotate(rotationTransform, 0.25 * M_PI_2, 0.0f, 1.0f, 0.0f);
weakSelf.viewHightScoreAvatar.layer.transform = rotationTransform;
[UIView animateWithDuration:2.0 delay:0 options: UIViewAnimationOptionRepeat |UIViewAnimationOptionAutoreverse animations:^{
CATransform3D rotationTransform2 = CATransform3DIdentity;
rotationTransform2 = CATransform3DRotate(rotationTransform2, -0.25* M_PI_2, 0.0f, 1.0f, 0.0f);
weakSelf.viewHightScoreAvatar.layer.transform = rotationTransform2;
} completion:^(BOOL finished) {
}];
經過多次查找資料跟不斷嘗試終於發現了問題所在,解決方法如下:
對於問題1:可以通過設置CALayer的zPosition來解決,zPosition表示UIView在UI渲染的時候,在屏幕上的層級,zPosition越大在越上面。
對於問題2:可以通過設置CATransform3D的m34來解決,m34表示透視效果,默認值是0(1/D),表示的是無窮遠( D無窮大)。當D越小,也就是m34越接近1,透視效果越明顯。
修改後的代碼如下:
CATransform3D rotationTransform = CATransform3DIdentity;
rotationTransform.m34 = -1.0f/200.0f;//注意這裡要在CATransform3DRotate前調用,否則看不效果。
rotationTransform = CATransform3DRotate(rotationTransform, 0.25 * M_PI_2, 0.0f, 1.0f, 0.0f);
weakSelf.viewHightScoreAvatar.layer.transform = rotationTransform;
weakSelf.viewHightScoreAvatar.layer.zPosition = 100;
[UIView animateWithDuration:2.0 delay:0 options: UIViewAnimationOptionRepeat |UIViewAnimationOptionAutoreverse animations:^{
CATransform3D rotationTransform2 = CATransform3DIdentity;
rotationTransform2.m34 = -1.0f/200.0f;
rotationTransform2 = CATransform3DRotate(rotationTransform2, -0.25* M_PI_2, 0.0f, 1.0f, 0.0f);
weakSelf.viewHightScoreAvatar.layer.transform = rotationTransform2;
weakSelf.viewHightScoreAvatar.layer.zPosition = 100;
} completion:^(BOOL finished) {
}];