3

SO (削除済み) で最近尋ねた関連する質問に対する回答を得るためにテスト プロジェクトを作成した後、カスタムUIViewサブクラス内でレイヤーを回転させるときに、似たような問題ではありますが、別の問題に遭遇しました。

iPhone シミュレーター セッションのビデオは、ここで見ることができます。

レイヤーは、必要に応じて z 軸を中心に回転するのではなく、対角線で x/y 軸を中心に回転しているように見えます。

ローテーションを実行するコードは、setAngle:次のように呼び出されるビュー セッター メソッド内にあります。

_imageLayer.transform = CATransform3DMakeRotation(angle / 180.0 * M_PI, 0.0, 0.0, 1.0);

(ここangleで度です)。

完全な Xcode プロジェクトは、ここから入手できます。

元のSOの質問は、デバイスの向きが変更された後にのみこの動作を示しているため、最初に思ったよりも理解にギャップがあるようです(OSXのバックグラウンドから来て、レイヤーを何度も使用しているため、そのような問題はないと予想していました)。

私の質問は、レイヤーが z 軸を中心に希望どおりに回転しないのはなぜですか?

4

2 に答える 2

2

私は答えようとしましたが、あなたは私を先取りしました! とにかく、これが私が言おとしていたことです(それは本当にあなたの最後のポイントに対処しています)

予期しない動作の主な理由は、変換されたオブジェクトにフレーム プロパティを設定していることです。これを行うことはできません - Apple はそれに対して警告します* : 変換が適用された後、frame プロパティは未定義の結果を返します。

だからあなたはこれをすべきではありません:

 //_imageLayer.frame = layerFrame;

ただし、設定boundscenterプロパティ ( positionCALayers の場合) は引き続き期待どおりに機能するため、代わりに次のようにすることができます。

   _imageLayer.bounds = (CGRect){0,0,min,min};
   _imageLayer.position = self.center;  


* UIView のフレーム プロパティのドキュメントを参照してください。

警告: transform プロパティが恒等変換でない場合、このプロパティの値は定義されていないため、無視する必要があります。

于 2013-02-16T14:31:40.710 に答える
0

OK、この問題は修正されました。更新されたプロジェクトはこちらです。

学んだ問題は次のとおりです。

  • ビューコントローラーの 内からビューのフレームを設定しないでくださいviewWillLayoutSubviewsこれが問題の根本原因である可能性があります。[ViewController _currentRect]ビューをウィンドウ境界に引き伸ばすように自動サイズ変更マスクが設定されている限り 、カスタム メソッドで実行される計算は必要ありません。

  • [UIView layoutSubviews]レイヤーが回転したときに呼び出されるようにレイヤーを配置しないでください(!!)。これは非効率的です。代わりに[UIView setBounds:]、レイヤーをレイアウトしていました。 setBounds:デバイスの向きが変更された後に呼び出されますが、奇妙な理由で新しく作成されたビューでは呼び出されないため、[UIView didMoveToSuperview]明示的に呼び出すようにオーバーライドしました( self.bounds = self.bounds;)。好奇心旺盛で好奇心旺盛。

  • レイアウト時にレイヤーを設定するのboundspositionはなく、レイヤーを設定しましたが、これが根本的な原因だと思いました(これを行った後、物事が機能し始めました)が、これがどのように違いを生むのかわかりません。これは治ったと思います最初の箇条書きで述べた間違いの副作用として更新:@He Wasの回答で指摘されているように。これ根本原因です。frame

私の解決策が100%「正しい」わけではないという痛みをまだ感じているので、この回答を正しいとはマークしません。

于 2013-02-16T14:14:14.573 に答える