【问题标题】:CGAffineTransformMakeRotation of subview子视图的 CGAffineTransformMakeRotation
【发布时间】:2012-06-23 18:49:41
【问题描述】:

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

在这个视图中,我有 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) 

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

为此,我在平台实现文件中创建了子视图(self.window)。我认为通过在此文件中执行此操作,坐标将与此视图相关。他们可能在轮换之前就想到了。但他们需要保持相对于旋转平台的位置,但方向与真北对齐。结果将是在每个平台上以这种方式绘制的矩形应该以相同的方式放置在每个平台上,但是矩形应该相对于平台旋转,即,根本不相对于 circusView(不要问我为什么叫马戏团——从另一个项目转换过来的)。

有什么建议吗?我现在在想,我必须像我最终让平台正常工作一样初始化塔,然后按照平台旋转的倒数旋转它们。

【问题讨论】:

  • 显示您对视图的实际操作。
  • 我不明白你的问题。现在,我只有一个包含线条和多边形的存根。最终,它将是this troll calendar 的模型。这是否回答你的问题?没有按钮、表格等。只有图形。
  • -drawRect: 应该绘制。它不应该改变视图的布局或旋转。在设置视图层次结构和/或更改 self.tagself.NumPlatforms 时执行此操作。

标签: objective-c view rotation transform subview


【解决方案1】:

不要在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);
    }
}

您可以通过向视图发送setNeedsLayout 来触发layoutSubviews,但您可能不需要这样做。系统还会在其他时间自动安排对layoutSubviews 的调用,例如当视图的大小发生变化或获得或失去子视图时。

【讨论】:

  • 我做了这个改变,仍然看到相同的行为,即子视图的旋转独立于主视图的旋转。我没有想到布局事件,因为一旦构建了主视图,布局就保持不变。它只需要旋转。旋转将随着设备的移动而发生,因此相同的子视图将始终位于 iPad 的北侧。不过,子视图彼此的相对排列在它们各自的上下文中将始终保持不变。
  • 暂停您的应用程序(在调试器中)并运行以下命令:po [[UIApp keyWindow] recursiveDescription]。将输出(会有很多)粘贴到您的问题中。
  • 我需要在任何特定时间暂停它吗?我在哪里输入命令?顺便说一句,Kirby Turner 和 Tom Harrington 合着的 Learning iPad Programming 使用了一个在本书进展过程中开发的应用程序。它包括一个轮子视图,允许视图围绕轮子旋转。该应用程序的工作方式与我的工作方式相同。但我希望子视图与它们的父视图一起旋转,而不是与包含父视图的窗口保持正交。这适用于 PhotoWheel 应用,但不适用于我的应用。
  • 我知道在哪里输入 po。抱歉,在此之前,我在学习如何输入调试命令的书籍中没有取得足够的进步。
  • 还有一个问题要问你们。你说我不应该在drawRect中这样做。但是,在 Apple 的视图文档中,它指出,“注意:出于性能原因,不鼓励旋转边界矩形。最好使用 drawRect: 方法中的图形运算符旋转坐标系,而不是旋转边界坐标系。请参阅“ Coordinate Systems and Transforms”在 Cocoa 绘图指南中以获取更多信息。“。你能澄清一下吗?附言如何在这些注释框中输入新行?当我按 ENTER 时,它会提交帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
相关资源
最近更新 更多