【问题标题】:UIView UIScrollview - frames, bounds, center confusionsUIView UIScrollview - 框架、边界、中心混乱
【发布时间】:2012-05-04 21:05:45
【问题描述】:

我将 UIImageView 放在 UIScrollView 中,并尝试控制图像,使其在缩放后以滚动视图为中心。而且我不确定最好的方法。

苹果文档告诉我们不要使用 frame 属性:“警告如果变换属性不是恒等变换,则此属性的值是未定义的,因此应该被忽略。”所以我尝试在 UIViewController 子类中使用以下内容,该子类的 xib 包含 scrollView 并包含 imageView:

scrollView.bounds =
    CGRectMake 
    (scrollView.contentSize.width/2 - scrollView.center.x,
     scrollView.contentSize.height/2 - scrollView.center.y,
     scrollView.bounds.size.width,
     scrollView.bounds.size.height);

containedView.center =    
    CGPointMake 
    (containedView.bounds.size.width*scrollView.zoomScale/2,
     containedView.bounds.size.height*scrollView.zoomScale/2);

当 containsView 的宽度和高度大于 scrollView 的宽度和高度时,这可以准确地工作,并设置视图,以便后续滚动将您准确地带到 containsView 的边缘。但是,当图像的任一尺寸小于 scrollView 的宽度和高度时,图像会被磁性吸引到屏幕的左上角。在 iPad 模拟器中(仅),当图像缩小到 minimumZoom 的大小时,它会锁定到屏幕的中心。磁吸引力非常平滑,就像在图像居中后 UI 中的某些内容覆盖了我的代码一样。它看起来有点像 CALayer contentsGravity ( kCAGravityTopLeft ) 的东西,也许吧?

Apple 在他们的代码示例 photoScroller(在 UIScrollView 的子类中)中反驳了他们自己的建议:

// center the image as it becomes smaller than the size of the screen

CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;

// center horizontally
if (frameToCenter.size.width < boundsSize.width)
    frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
    frameToCenter.origin.x = 0;

// center vertically
if (frameToCenter.size.height < boundsSize.height)
    frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
    frameToCenter.origin.y = 0;

imageView.frame = frameToCenter;

当图像较小时,此方法可以更好地居中,但是当我在我的项目中尝试此方法时,它会引入某种不一致。例如,在 scrollView.bounces = NO 的情况下,高度小于 scrollView 高度但宽度更大(因此可以从左到右滚动)的水平图像将比它应该向左滚动更远(当向右滚动它会在图像的边缘正确停止,尽管如果 scrollView.bounces = YES 它会从边缘反弹,因此图像总是在左侧裁剪)当图像在两个维度上都大于其包含的滚动视图时这个问题更加突出,整个结果让人感觉很糟糕,考虑到 Apple 的书面建议,这不足为奇。

我已经搜索了论坛,但找不到太多关于此的评论。我是否遗漏了一些非常明显的东西?

【问题讨论】:

    标签: ios objective-c cocoa-touch uiview uiscrollview


    【解决方案1】:

    您似乎没有使用transform 属性,因此您可以忽略有关在使用transform 属性时不使用frame 属性的警告。继续使用 frame 属性,就像 Apple(和我们其他人)一样。

    【讨论】:

    • scrollViewDidZoom 在放大和缩小时调用该方法 - 所以变换不再是身份变换?无论如何,上面提到的框架正在引入这个滚动故障。当我对每个算法使用的数字进行 NSLog 记录时,它们似乎是相同的,所以我觉得这有点神秘
    • 更准确地说,滚动视图的身份转换保持不变,但缩放会改变 imageView 的身份转换。所以我可以使用滚动视图的框架,但我没有用。
    • 我在设置将图像导入滚动视图的算法时首先发现了这个故障。我将它们设置为“方面填充”滚动视图,并注意到图像并不总是正确导入,有时即使使用相同的图像也会出现任意大小。我停止使用 frame 属性,问题就消失了(但我得到了这个问题来弥补它!)
    • 我错过了您正在缩放 UIScrollView。这是我不处理的复杂性。在我的照片库中,我使用滚动视图进行滚动,而不是缩放。我根据 UIScrollView 中所需的坐标和大小设置 UIImages 的框架。所以这一切都非常简单,这些东西会以我放置的尺寸精确地显示在我放置的位置。我设置了 UIScrollView contentSize 以确保它足够大以包含我所有的 UIImages。您显然在尝试做一些更复杂的事情,但听起来您在解决问题方面取得了进展。
    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    相关资源
    最近更新 更多