Objective c 获取UIScrollView的可见矩形';内容
我怎样才能找到屏幕上实际可见的显示视图内容的rect(CGRect)Objective c 获取UIScrollView的可见矩形';内容,objective-c,iphone,uiscrollview,Objective C,Iphone,Uiscrollview,我怎样才能找到屏幕上实际可见的显示视图内容的rect(CGRect) myScrollView.bounds 上面的代码在没有缩放的情况下工作,但一旦允许缩放,它将在缩放比例不是1的情况下中断 为了澄清,我需要一个CGRect,它包含滚动视图内容相对于内容的可见区域。(也就是说,如果是缩放比例2,矩形的大小将是滚动视图大小的一半,如果是缩放比例0.5,则将是两倍。)我不认为UIScrollView直接提供了矩形,但我认为您已经具备了计算矩形的所有必要项 创建要查找的矩形只需边界、content
myScrollView.bounds
上面的代码在没有缩放的情况下工作,但一旦允许缩放,它将在缩放比例不是1的情况下中断
为了澄清,我需要一个CGRect,它包含滚动视图内容相对于内容的可见区域。(也就是说,如果是缩放比例2,矩形的大小将是滚动视图大小的一半,如果是缩放比例0.5,则将是两倍。)我不认为UIScrollView直接提供了矩形,但我认为您已经具备了计算矩形的所有必要项
创建要查找的矩形只需边界、contentOffset和zoomScale的组合。您必须使用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;
}
CGFloat scale=(CGFloat)1.0/scrollView.zoomScale;
if(isless(scale,1.0))//您需要#包含for isless()
{
visibleRect.origin.x*=比例;
visibleRect.origin.y*=刻度;
visibleRect.size.width*=比例;
visibleRect.size.height*=比例;
}
旁白:我使用math.h中的isless()、isgreater()、isequal()等,因为它们(大概)在处理“无序”浮点比较结果和其他奇怪而奇妙的特定于体系结构的FP情况时是正确的
编辑:在计算
visibleRect.size时,您需要使用bounds.size
而不是contentSize
来回答我自己的问题,这主要要感谢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()
的用途,它会在代码更大时破坏代码。或者您可以简单地执行
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;
CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:zoomedSubview];
迅捷的
较短版本:
CGRect visibleRect = CGRectApplyAffineTransform(scrollView.bounds, CGAffineTransformMakeScale(1.0 / scrollView.zoomScale, 1.0 / scrollView.zoomScale));
我不确定这是否是定义的行为,但几乎所有UIView子类的边界的原点都设置为(0,0)。但是,UIScrollView将原点设置为contentOffset
更一般的解决方案是:
[scrollView convertRect:scrollView.bounds
toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
Swift 4.0:
我的答案适用于Swift 4.0:
let visible = scrollView.convert(scrollView.bounds, to: subView)
其中,scrollView
是滚动的视图,subView
是可缩放的滚动视图中的视图,它包含滚动中的所有内容。我认为visibleRect.size=scrollView.frame.size;非contentSize))@property(非原子)CGSize contentSize;//iOS 3.2+和CATiledLayer的默认CGSizeZeroThis似乎失败-scrollView的zoomScale始终设置为(例如,在iPad上:)“2.0”,无论发生什么情况。我知道UIScrollView在iOS 3.2中发生了变化——也许它打破了这种变通方法?或者是CATiledLayer破坏了它?SighUPDATE:这在iOS 4+上确实有效-除非您忘记实现UIScrollViewDelegate方法“ScrollViewDiEndZooming:withView:atScale:”。注意:方法可以为空!但这是苹果的一个实现缺陷,如果方法不存在。。。苹果没有更新他们自己的ZoomSale属性(谁知道还有什么bug?@kenneth Ballengger你的代码中的“比例”(float theScale=1.0/scale;)是什么?事实上,特伦斯科下面的答案要好得多。让系统来帮你吧。你的问题本身就解决了我的问题。我在找scrollview的可见矩形+1。zoomedSubview是您不想获取其可见矩形的子视图。zoomedSubview是在“scrollView”中放大/缩小或滚动的UIView。它与实现UIScrollViewDelegate的(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView方法返回的UIView相同。
let visible = scrollView.convert(scrollView.bounds, to: subView)