0

这是场景。我有一个主视图,我想将其方向与真北对齐。

在这个视图中,我有 7 个子视图围绕主视图的中心以七边形图案排列。这些子视图中的每一个都与其他子视图基本相同,因此相对于它们的局部坐标进行绘制是最有意义的。

我想我会使用 CGAffineTransformMakeRotation 将子视图旋转 2*M_PI/7 的整数倍,以便正确排列它们。到目前为止,一切都很好。

我还想我会使用 CGAffineTransformMakeRotation 根据罗盘值旋转主视图。为了测试这一点,到目前为止,我只是对值进行了硬编码。那也很好。

问题是,我得到的行为与我的预期不同。我认为子视图的旋转将相对于主视图,但它似乎是相对于包含主视图的窗口。我有错误的期望吗?我需要为子视图旋转组合两个转换吗?如果我必须这样做,那很好,但它与我的预期不同,所以也许我做错了什么。

这是旋转主视图的代码。我目前将它作为主视图的 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现在我遇到了另一个障碍。我认为已经解决了上述情况,下一步会很简单,但事实证明这是一个挑战。您可能希望在评论部分关注我的链接,以查看模型在纸/铅笔和/或 Google Sketchup 渲染时的样子。无论如何,下一步就是在平台上放塔。我创建了一个名为 Tower 的新子类 UIView,目的是在每个平台上放置三个塔。棘手的部分是方向需要匹配真北,即circusView 方向,但放置需要与平台对齐。

为此,我在平台实现文件中创建了子视图(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 回答