web-dev-qa-db-ja.com

UIScrollViewのコンテンツの可視四角形を取得する

実際に画面に表示される表示ビューのコンテンツの四角形(CGRect)を見つけるにはどうすればよいですか。

myScrollView.bounds

上記のコードは、ズームがないときに機能しますが、ズームを許可するとすぐに、1以外のズームスケールで壊れます。

明確にするために、スクロールビューのコンテンツの可視領域を、コンテンツと比較して含むCGRectが必要です。 (つまり、ズームスケールが2の場合、四角形のサイズはスクロールビューのサイズの半分になり、ズームスケールが0.5の場合は2倍になります。)

69

私自身の質問に答えたのは、主に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()の使用法がわかりませんでした。

83

または、単に行うことができます

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

Swift

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

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()などを使用します。これらは(おそらく)「順序付けられていない」浮動小数点比較結果やその他の奇妙で素晴らしいアーキテクチャ固有のFP件。


編集:bounds.sizeを計算するときは、contentSizeの代わりにvisibleRect.sizeを使用する必要があります。

28
Jim Dovey

短いバージョン:

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

これが定義された動作であるかどうかはわかりませんが、ほぼすべてのUIViewサブクラスのboundsのOriginは(0,0)に設定されています。ただし、UIScrollViewsのOriginはcontentOffsetに設定されています。

10
Frank Schmitt

もう少し一般的な解決策は次のとおりです。

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
5
CGRect visibleRect;
visibleRect.Origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;
2
Bas Dirkse

Swift 4.0:

私の答えは適応します Trenskowの答え to Swift 4.0:

let visible = scrollView.convert(scrollView.bounds, to: subView)

ここで、scrollViewはスクロールのビューであり、subViewはズーム可能なscrollView内のビューであり、スクロール可能なすべてのコンテンツが含まれます。

0
RoberRM

UIScrollViewがその四角形を直接提供するとは思いませんが、計算に必要なすべてのアイテムがあると思います。

境界、contentOffset、zoomScaleの組み合わせは、探している長方形を作成するのに必要なものだけです。

0