获取UIScrollView内容的可见rect

时间:2009-05-15 12:05:39

标签: objective-c iphone uiscrollview

如何查找屏幕上实际可见的显示视图内容的rect(CGRect)。

myScrollView.bounds

上面的代码在没有缩放时有效,但只要你允许缩放,它就会以1以外的缩放比例中断。

为了澄清,我想要一个CGRect,它包含相对于内容的滚动视图内容的可见区域。 (即如果它是缩放比例2,则rect的大小将是滚动视图大小的一半,如果它在缩放比例为0.5时,它将是双倍。)

8 个答案:

答案 0 :(得分:106)

或者你可以简单地做

CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:zoomedSubview];

夫特

let visibleRect = scrollView.convert(scrollView.bounds, to: zoomedSubview)

答案 1 :(得分:82)

回答我自己的问题,主要是感谢Jim Dovey的答案,这个答案并没有完全解决问题,但给了我答案的基础:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.bounds.size;

float theScale = 1.0 / scale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;

主要区别在于visibleRect的大小应该是scrollView.bounds.size,而不是scrollView.contentSize,这是内容视图的大小。还简化了数学,并没有完全看到isless()的使用,它会在代码更大时破坏代码。

答案 2 :(得分:28)

您必须使用UIScrollView的contentOffset和contentSize属性计算它,如下所示:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.contentSize;

然后,您可以将其记录下来进行健全性测试:

NSLog( @"Visible rect: %@", NSStringFromCGRect(visibleRect) );

考虑到缩放(如果这还没有被contentSize属性完成),您需要将每个坐标除以zoomScale,或者为了获得更好的性能,您将乘以1.0 / zoomScale:

CGFloat scale = (CGFloat) 1.0 / scrollView.zoomScale;
if ( isless(scale, 1.0) )      // you need to #include <math.h> for isless()
{
    visibleRect.origin.x *= scale;
    visibleRect.origin.y *= scale;
    visibleRect.size.width *= scale;
    visibleRect.size.height *= scale;
}

除此之外:我在math.h中使用isless(),isgreater(),isequal()等因为这些(可能)对于“无序”浮点比较结果和其他奇怪的&amp;精彩的架构专用FP案例。


修改:在计算bounds.size时,您需要使用contentSize代替visibleRect.size

答案 3 :(得分:10)

更短的版本:

CGRect visibleRect = CGRectApplyAffineTransform(scrollView.bounds, CGAffineTransformMakeScale(1.0 / scrollView.zoomScale, 1.0 / scrollView.zoomScale));

我不确定这是否是已定义的行为,但几乎所有UIView子类都将其bounds的原点设置为(0,0)。但是,UIScrollViews的原点设置为contentOffset

答案 4 :(得分:5)

更通用的解决方案是:

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];

答案 5 :(得分:2)

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;

答案 6 :(得分:0)

我不认为UIScrollView直接给你那个矩形,但我认为你有计算它的所有必要项目。

边界,contentOffset和zoomScale的组合应该是创建您正在寻找的矩形所需的全部。

答案 7 :(得分:0)

Swift 4.0:

我的回答使Trenskow's answer适应了Swift 4.0:

async/await

其中let visible = scrollView.convert(scrollView.bounds, to: subView) 是滚动视图,scrollViewsubView内部的视图,该视图是可缩放的并且包含滚动内部的所有内容。