【问题标题】:Get size of UIView after applying CGAffineTransform应用 CGAffineTransform 后获取 UIView 的大小
【发布时间】:2010-04-22 21:50:19
【问题描述】:

我很惊讶没有找到这个问题的答案,也许是我忽略了一些非常简单的事情:

应用 CGAffineTransform 后如何获得 UIView 的实际大小?

例如。

我的 UIView 的大小为 300 x 200,我应用了缩放变换,比如说水平和垂直的因子 2,所以 UIView 现在在屏幕上占用 600 x 400,但它是边界,它的层边界仍然返回大小300 x 200 ...我在哪里可以找到 UIView 的实际尺寸?

ps。忘了提我还想旋转uiview。如果我只应用缩放 CGSizeApplyAffineTransform 效果很好,但是当还有旋转时,它就不能正常工作。

编辑:drawonward 为我指明了正确的方向,我只是对要编译的代码进行了一些改进,这里是:

UIView* view = (your view being transformed);
CGAffineTransform trans = (view.transform or create a new transformation);

CGRect rect = [view bounds];
CGMutablePathRef path = CGPathCreateMutable();
rect.origin = CGPointZero;
CGPathAddRect(path , &trans , rect);
rect = CGPathGetBoundingBox( path );
CGPathRelease( path );

现在 rect.size 包含应用了转换的视图的尺寸 再次感谢drawonward

【问题讨论】:

    标签: objective-c uiview cgaffinetransform


    【解决方案1】:

    我在 Objective C 中使用它:

    CGRect transformedBounds = CGRectApplyAffineTransform(view.bounds, view.transform);
    

    或在 Swift 4 中:

    let transformedBounds = view.bounds.applying(view.transform)
    

    【讨论】:

    • 我相信“view.bounds”会是一个更好的答案。你为什么要在这里改变边界而不是只取框架的大小?
    【解决方案2】:

    [myView frame] 返回父视图的框架,用于布局和相对大小。 [myView bounds] 返回视图本身的边界,用于绘图。如果您对多个视图应用了变换,则可以使用convertRect: 与一个视图进行转换。

    编辑:

    可能是这样的。

    CGRect rect = [view bounds];
    CGPathRef path = CGPathCreateMutable();
    rect.origin = CGPointZero;
    CGPathAddRect( rect , [view transform] );
    rect = CGPathGetBoundingBox( path );
    CGPathRelease( path );
    

    使用[view center]在superview中查找位置。

    【讨论】:

    • 这是来自苹果文档的关于“框架”的文档:警告:如果转换属性不是身份转换,则此属性的值未定义,因此应忽略。因此,当应用了转换时,框架是没有问题的。并且“边界”总是返回原始大小
    • 确实!啊,这个我总是忘记的函数库 - CGPathGetBoundingBox 是诀窍。我用工作代码编辑了问题,非常感谢
    • 还要注意 center 属性应该可以工作,即使是非身份转换。
    【解决方案3】:

    老问题,但在搜索解决方案和大量尝试后遇到了这里。很简单;

    view.layer.frame 应用了所有转换,您可以轻松地从view.layer.frame.size 获得大小。

    -- 下面不是这个问题的答案--

    对于我的问题,我试图在更改旋转视图的layer.anchorPoint 后计算新的center 值,因此它不会移动。最后是这样的;

    CGPoint topLeft = [self.superview convertPoint:CGPointMake(0, 0) fromView:self];
    self.layer.anchorPoint = CGPointMake(0, 0);
    self.center = topLeft;
    

    反向

    CGPoint center = [self.superview convertPoint:CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2) fromView:self];
    self.layer.anchorPoint = CGPointMake(.5, .5);
    self.center = center;
    

    终于。

    【讨论】:

      【解决方案4】:

      使用CGSizeApplyAffineTransform(size, transform),它将返回转换后的大小。还有类似的CGPointCGRect 函数。

      【讨论】:

      • 当 CGSizeApplyAffineTransform 也包含旋转时,这将无法正常工作,但在仅应用缩放的情况下,您是对的。 (我的错误我的问题中没有包括轮换)
      【解决方案5】:

      更简单:应用了变换 tr 的(边界)大小为 s 的视图具有结果大小:

      CGSizeMake(s.width*hypotf(tr.a, tr.b), s.height*hypotf(tr.c, tr.d))
      

      但是,如果视图的父视图或任何祖先视图应用了任何非单位变换,则此大小在绝对意义上没有什么意义。

      如果您想在对视图或其父视图应用任意变换后获得窗口坐标中视图的绝对大小,您应该首先通过将所有视图变换组合到根窗口来计算绝对变换矩阵,然后然后将上述公式应用于结果。

      【讨论】:

        【解决方案6】:

        但是你应用了一个旋转变换,它没有通过 CGPathGetBoundingBox 得到正确的大小。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-31
          • 1970-01-01
          • 1970-01-01
          • 2022-06-16
          相关资源
          最近更新 更多