【问题标题】:CATiledLayer gets a incorrect frame & contextCTM.a value (zoomScale)CATiledLayer 获得不正确的帧和 contextCTM.a 值 (zoomScale)
【发布时间】:2011-01-04 08:35:23
【问题描述】:

在 WWDC2010 Session 104 之后,我刚刚在 UIScrollView 中为 10000 x 8078 像素的图像创建了一个 CATiledLayer。

当视图首次显示在其顶层时,我对框架和zoomScale 感到困扰

  1. 就像在会话 104 中一样,我将 levelsOfDetail 定义为 4
  2. 在我的drawRect中我调用CGFloat lScale = CGContextGetCTM(lContext).a;

奇怪的是,在运行时 lScale 被分配了 0.124907158,而不是预期的 0.125。

传递给drawRectrect 也有浮点值,例如

  • rect.origin.x = 4099.04443
  • rect.origin.y = 6144
  • rect.size.width = 2049.52222
  • rect.size.height = 2048

最让我恼火的是CATiledLayer 的框架显示的原点是 0 x 26.93,即使我使用 initWithFrame 使用 0x0 原点创建了 tiledImageView。

我有什么想法可以找到对此负责的计算吗?


编辑: 我找到了奇怪框架位置的来源,即 ScrollView 边界被错误地设置为 450 像素。那应该是 420 像素。 UIScrollView 中的 layoutSubview 例程有一个中心视图例程,它无意中调整了 y 坐标。

【问题讨论】:

    标签: iphone uiscrollview catiledlayer


    【解决方案1】:

    我找到了解决这个问题的方法。

    WWDC 2010 会话 104 示例有两个控制视图行为的 UIScrollView 方法。

    第一个是configureForImageSize,我在之前发布的答案中提到了缩放比例的设置。

    由于解释的浮点差异,imageView-bounds 会生成前面突出显示的小数(参见 wx/hx 或 wy/hy)。

    为了清理它,我使用了 layoutSubviews 的覆盖,我在其中计算了视图框架:

    - (void) layoutSubviews {
        [super layoutSubviews];
    
        CGSize lBoundsSize = self.bounds.size;
        CGRect lFrameToCenter = imageView.frame;
    
        // cure to the decimals problem
        lFrameToCenter.size.width  = roundf(lFrameToCenter.size.width);
        lFrameToCenter.size.height = roundf(lFrameToCenter.size.height);
    
        if (lFrameToCenter.size.width < lBoundsSize.width)
            lFrameToCenter.origin.x = (lBoundsSize.width - lFrameToCenter.size.width) / 2;
        else
            lFrameToCenter.origin.x = 0;
    
        if (lFrameToCenter.size.height < lBoundsSize.height)
            lFrameToCenter.origin.y = (lBoundsSize.height - lFrameToCenter.size.height) / 2;
        else
            lFrameToCenter.origin.y = 0;
    
        imageView.frame = lFrameToCenter;
    
        if ([imageView isKindOfClass:[tileView class]]) {
            imageView.contentScaleFactor = 1.0;
        }
    }
    

    请注意,在对帧大小进行任何其他操作之前,我会对其进行四舍五入!

    【讨论】:

    • 你刚刚解决了我几个小时以来一直在努力解决的问题。 :-) 我有一个完美工作的 CATiledLayer,但是当我试图改变它的位置(帧)时,比例值突然从例如改变。 0.5 至 0.49756。我尝试了您的解决方案并将 CATiledLayer 的宽度和高度四舍五入,现在它可以工作了!感谢您分享您自己找到的解决方案。 :-)
    • 好吧,它确实解决了问题,但它引入了另一个问题。当您放大到 UIScrollView 时,您会看到 CATiledLayer 的大小相对于 UIScrollView 不正确。可以看到是因为右下边缘变黑了,因为CATiledLayer没有完全填满UIScrollView,然后就可以看到UIScrollView的背景色了。在某些情况下这可能没问题,但不幸的是,我的情况并非如此。我将不得不尝试其他方法,也许是四舍五入。
    【解决方案2】:

    我的错误分析更进一步。

    UIScrollView 中具有 10000x8078 和 320x450 的 mImageSize 边界,我使用会话 104 示例中的configureForImageSize 计算如下:

    - (void) configureForImageSize:(CGSize)mImageSize  {
        CGSize lBoundsSize = [self bounds].size;
    
        // set up our content size and min/max zoomscale
        CGFloat lXScale = lBoundsSize.width / mImageSize.width;    // the scale needed to perfectly fit the image width-wise
        CGFloat lYScale = lBoundsSize.height / mImageSize.height;  // the scale needed to perfectly fit the image height-wise
    
        // debug values
        float wx = mImageSize.width  * lXScale;
        float wy = mImageSize.width  * lYScale;
        float hx = mImageSize.height * lXScale;
        float hy = mImageSize.height * lYScale;
    
        ...
    }
    

    调试器显示以下值:

    * mImageSize = width 10000 height 8078
    * bounds size: width 320 height 450
    * lXScale = 0.0396137647
    * lYScale = 0.0450000018
    * wx = 320
    * wy = 363.51001
    * hx = 396.137634
    * hy = 450.000031
    

    所以我收集与边界相关的图像大小会导致浮点计算差异。当CATiledLayer 生成时,边界总是浮点值。

    如果这是原因,我怎样才能在不调整图像大小的情况下获得数学方法(丑陋的想法)???

    【讨论】:

    • 即使在将宽度和高度四舍五入后,我仍然会得到一个奇怪的比例,比如 0.249921,导致应用程序无法找到合适的图块。我该如何解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2019-08-19
    • 2013-05-29
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多