0

これがシナリオです。真北に合わせたい向きのメインビューがあります。

このビューの中には、メインビューの中央に七角形に配置された7つのサブビューがあります。これらのサブビューはそれぞれ基本的に他のサブビューと同じであるため、ローカル座標を基準にして描画するのが最も理にかなっています。

サブビューを適切に配置するために、CGAffineTransformMakeRotationを使用してサブビューを2 * M_PI/7の整数倍で回転させると思いました。ここまでは順調ですね。

また、CGAffineTransformMakeRotationを使用して、コンパスの値に従ってメインビューを回転させることも考えました。それをテストするために、これまで私は値をハードコーディングしてきました。それも結構です。

問題は、私が期待したものとは異なる振る舞いをしているということです。サブビューの回転はメインビューを基準にすると思いましたが、代わりにメインビューを含むウィンドウを基準にしたようです。私は間違った期待を持っていましたか?サブビューの回転のために2つの変換を構成する必要がありますか?それが必要な場合は問題ありませんが、予想とは異なるため、何か間違ったことをしている可能性があります。

メインビューを回転させるコードは次のとおりです。私は現在、メインビューのmファイルのdrawRectの最後のものとしてそれを持っています。

      float angleFromNorth = 2*43.0 / M_PI;
  //      angleFromNorth = 0.;
  CGAffineTransform transform = CGAffineTransformMakeRotation(angleFromNorth);
  [self setTransform:transform];

各サブビューを回転させるコードは次のとおりです。このコードは、サブビューのdrawRectメソッドに含まれています。サブビューは、メインビューのmファイルに作成されます。

      float angle = 2 * M_PI * self.tag / self.NumPlatforms;
  CGAffineTransform transform = CGAffineTransformMakeRotation(angle);
  [self setTransform:transform];

    (lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $1 = 0x06c78ff0 <UIWindow: 0x6c80370; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x6c80450>>
   | <CircusView: 0x6c807a0; frame = (0 0; 768 1024); layer = <CALayer: 0x6c80a40>>
   | <PlatformView: 0x8880cd0; frame = (234 362; 300 300); layer = <CALayer: 0x887d310>>
   | <PlatformView: 0x6c805f0; frame = (173.202 301.202; 421.596 421.596); transform = [0.62349, 0.781832, -0.781832, 0.62349, 0, 0]; tag = 1; layer = <CALayer: 0x6c80820>>
   | <PlatformView: 0x6c81870; frame = (204.383 332.383; 359.235 359.235); transform = [-0.222521, 0.974928, -0.974928, -0.222521, 0, 0]; tag = 2; layer = <CALayer: 0x6c80630>>
   | <PlatformView: 0x8884710; frame = (183.772 311.772; 400.456 400.456); transform = [-0.900969, 0.433884, -0.433884, -0.900969, 0, 0]; tag = 3; layer = <CALayer: 0x887cd80>>
   | <PlatformView: 0x6a91a60; frame = (183.772 311.772; 400.456 400.456); transform = [-0.900969, -0.433884, 0.433884, -0.900969, 0, 0]; tag = 4; layer = <CALayer: 0x6a8a200>>
   | <PlatformView: 0x688f970; frame = (204.383 332.383; 359.235 359.235); transform = [-0.222521, -0.974928, 0.974928, -0.222521, 0, 0]; tag = 5; layer = <CALayer: 0x688a710>>
   | <PlatformView: 0x8884750; frame = (173.202 301.202; 421.596 421.596); transform = [0.62349, -0.781832, 0.781832, 0.62349, 0, 0]; tag = 6; layer = <CALayer: 0x887e290>>
(lldb) 

PS今、私は別のハードルに遭遇しました。上記のシナリオを解決したので、次のステップは簡単だと思いましたが、それは挑戦であることが判明しています。コメントセクションの私のリンクをたどって、紙/鉛筆やGoogleSketchupでレンダリングされたモデルがどのように見えるかを確認することをお勧めします。とにかく、次のステップはプラットフォームにタワーを配置することです。各プラットフォームに3つのタワーを配置することを目的として、Towerという新しいサブクラスUIViewを作成しました。トリッキーな部分は、向きが真の北、つまりサーカスビューの向きと一致する必要があることですが、配置はプラットフォームと整列する必要があります。

これを行うために、プラットフォーム実装ファイルに(self.windowの)サブビューを作成しました。このファイル内でそれを行うことにより、座標はこのビューに相対的であると思いました。そして、彼らはおそらく、ローテーションの前に、それについて考えるようになります。ただし、回転したプラットフォームを基準にして位置を維持する必要がありますが、真北に揃える必要があります。その結果、各プラットフォームでこのように描画された長方形は、各プラットフォームで同じ方法でプラットフォームに配置される必要がありますが、長方形はプラットフォームに対して回転する必要があります。つまり、circusViewに対してまったく回転しない必要があります(質問しないでください)。なぜそれがサーカスと呼ばれるのか-別のプロジェクトからの変換から残ったもの)。

助言がありますか?私は今、私が最終的にプラットフォームを機能させるのと同じ方法でタワーを初期化し、次にプラットフォームの回転の逆でそれらを回転させる必要があると考えています。

4

1 に答える 1

2

サブビューの変換をで設定しないでくださいdrawRect:layoutSubviews親にそれをしなさい。

static CGFloat radiansForDegrees(CGFloat degrees) {
    return degrees * 2 * M_PI / 360;
}

- (void)layoutSubviews {
    self.transform = CGAffineTransformMakeRotation(radiansForDegrees(43));

    CGFloat count = self.platformViews.count;
    for (UIView *platformView in self.platformViews) {
        platformView.transform = CGAffineTransformMakeRotation(platformView.tag * 2 * M_PI / count);
    }
}

layoutSubviewsビューに送信することでトリガーできsetNeedsLayoutますが、おそらくそうする必要はありません。layoutSubviewsまた、システムは、ビューのサイズが変更されたときや、サブビューを取得または失ったときなど、他の時間への呼び出しを自動的にスケジュールします。

于 2012-06-23T20:23:27.107 に答える