如何查找屏幕上实际可见的显示视图内容的rect(CGRect)。
myScrollView.bounds
上面的代码在没有缩放时有效,但只要你允许缩放,它就会以1以外的缩放比例中断。
为了澄清,我想要一个CGRect,它包含相对于内容的滚动视图内容的可见区域。 (即如果它是缩放比例2,则rect的大小将是滚动视图大小的一半,如果它在缩放比例为0.5时,它将是双倍。)
答案 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)
是滚动视图,scrollView
是subView
内部的视图,该视图是可缩放的并且包含滚动内部的所有内容。