2011-12-29 7 views
15

の正しいフレームの設定:は、一言で言えば、新しく作成されたCAShapeLayer

  1. あなたが設定した場合
  2. Appleは自動的CAShapeLayerためframeまたはboundsを設定しません(とAppleが[UIView sizeThatFits]と同等のものを実装していません)フレームのサイズを使用してパスのバウンディングボックス...すべてがうまくいかない。どんなにあなたがそれを設定しようとする方法、それはねじアップパス

ので、プログラムでCGPath新たに追加されたとCAShapeLayer新しく作成されたの枠を設定する正しい方法は何ですか?アップル社のドキュメントは、この件について黙っている。動作しない、私が試した

物事、:

  1. 層のframeをチェック層
  2. に追加し、CGPathを作成CAShapeLayer
  3. を作成する - それが{{0,0},{0,0}}
  4. ですセット:layer.frame = CGPathGetBoundingBox(layer.path)
  5. フレームは正しくなりましたが、パスは現在DOUBLEオフセットになっています - 0123を変更しましたパスが効果的に余分な(x,y)ピクセル

  6. セットにシフトすることになり:layer.bounds = CGPathGetBoundingBox(layer.path)

  7. を...それはすべてのナットを行きます。何も意味をなさない
  8. することで修正してください。layer.position = CGPathGetBoundingBox(layer.path).origin
  9. ...いいえサイコロ;まだナッツ。

ことの一つは、私が仕事をしたとしようとしたが、他の場所で問題が発生しました:

EDITは:これはあなたが画面を自動回転させるとすぐにBREAKS。私の推測:アップルの自動回転は、 "変換"プロパティの制御を必要とします。

  1. 層に追加
  2. は、レイヤーのフレームをチェックし、CGPathを作成CAShapeLayer
  3. を作成する - それが{{0,0},{0,0}}
  4. セットの:layer.frame = CGPathGetBoundingBox(layer.path)
  5. セット:layer.transform = CGAffineTransformMakeTranslation(CGPathGetBoundingBox(layer.path).origin.x * -1, // same for y-coord: set it to "-1 * the path's origin

この作品は、しかし...多くのサードパーティコードは、最初の変換fまたはCALayerはIDです。

これは難しくありません。確かに私はここで間違っている何かがありますか?

(「パスを追加するたびに、手動ですべてのポイントを手動で移動して-1 * (top-left-point.x, top-left-point.y)を移動する」という提案が1つありました。繰り返しますが、うまくいけば複雑です)

+0

解決方法を見つけましたか? – jannej

+0

まだありません。私は現在、質問自体から回避策を使用しています。それは遅く、維持する痛みです。問題はAppleのコードのバグだと思うのだろうか? – Adam

+3

小規模な補遺が1つあります。私は最終的に ".frame"がAppleによってサポートされていないことを発見しました。これはいたるところで使用されているため、これは奇妙ですが、ドキュメントやAppleのメーリングリストで十分深く掘り下げて読んだら、アップルのエンジニアから、それがうまくいかないと言って、バグを修正しないというメモが見つかりました。あなたは、すべてのために.boundsを使用し、 "readonly"として.frameを扱うことが期待されています。だから特に皮肉なことに、この設定では、.frameが "うまく動作しない"設定の "ほぼ動作します"。 – Adam

答えて

4

layer.boundsをパス境界に設定するのは正しいことです。レイヤのローカル座標空間をパスに一致させたいとします。しかし、レイヤーのpositionプロパティを設定してスーパーレイヤーの適切な場所に移動する必要があります。

(.frameと設定すると、.boundsと.positionの正しい値を計算するフレームワークに変換されますが、常にbounds.originは変更されません。パスの境界がゼロではない場合。)

だから、このようなものは、あなたがその通常の(0.5、0.5)の値からanchorPointを変更し、そのスーパーレイヤの原点にフラッシュ層を配置したくなかったと仮定すると、動作するはずです:

CGRect r = CGPathGetBoundingBox(layer.path); 
layer.bounds = r; 
layer.position = CGPointMake(r.size.width*.5, r.size.height*.5);