programing

UIScrollView 콘텐츠의 표시된 정류 가져오기

oldcodes 2023. 8. 22. 22:29
반응형

UIScrollView 콘텐츠의 표시된 정류 가져오기

실제로 화면에 표시되는 보기 내용의 정류(CGRect)를 확인하려면 어떻게 해야 합니까?

myScrollView.bounds

위의 코드는 확대/축소가 없을 때 작동하지만 확대/축소를 허용하는 즉시 1이 아닌 다른 확대/축소 배율에서 끊어집니다.

명확하게 하기 위해, 저는 스크롤 뷰의 콘텐츠에서 보이는 부분을 내용과 비교하여 포함하는 CGRect를 원합니다. (즉, 확대/축소 배율 2일 경우, 직사각형의 크기는 스크롤 뷰 크기의 절반, 확대/축소 배율 0.5일 경우, 두 배가 됩니다.

아니면 간단히 할 수도 있습니다.

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

스위프트

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

제 질문에 대답하는 것은, 주로 짐 도비의 대답 덕분입니다. 그 대답은 별로 효과가 없었지만, 제가 대답할 수 있는 근거를 마련해 주었습니다.

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;

주요 차이점은 눈에 보이는 Rect의 크기가 다음과 같아야 한다는 것입니다.scrollView.bounds.size,보다는scrollView.contentSize내용 보기의 크기입니다.또한 수학을 조금 단순화했고, 그것이 사용되는 것을 제대로 못했습니다.isless()더 클 때마다 암호를 해독할 수 있을 겁니다

다음과 같이 UIScrollView의 contentOffset 및 contentSize 속성을 사용하여 계산해야 합니다.

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

그런 다음 건전성 검사를 위해 로그에 기록할 수 있습니다.

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

contentSize 속성에서 아직 수행하지 않은 경우 확대/축소를 고려하려면 각 좌표를 zoomScale로 나누어야 합니다. 그렇지 않으면 성능을 향상시키려면 1.0 / 확대/축소 배율:

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;
}

추가: 저는 isless(), isgreater(), islater()를 math.h와 동일하게 사용합니다. 왜냐하면 이것들은 '순서가 없는' 부동 소수점 비교 결과 및 기타 이상하고 멋진 아키텍처 특정 FP 사례에 대해 올바른 작업을 수행할 것이기 때문입니다.


편집: 사용해야 합니다.bounds.size대신에contentSize계산할 때visibleRect.size.

단축 버전:

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

이것이 정의된 동작인지 확실하지 않지만 거의 모든 UIView 하위 클래스는 그들의 기원을 가지고 있습니다.bounds(0,0)으로 설정합니다.그러나 UIScrollViews의 오리진은 다음과 같이 설정됩니다.contentOffset.

좀 더 일반적인 해결책은 다음과 같습니다.

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;

Swift 4.0:

제 답변은 Swift 4.0에 대한 Trenckow의 답변을 적용한 것입니다.

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

어디에scrollView스크롤의 보기입니다.subView내부의 모습입니다.scrollView확대/축소 가능하며 스크롤 내부의 모든 내용을 포함합니다.

UIScrollView가 직사각형을 직접 제공하는 것은 아니지만 계산에 필요한 모든 항목을 가지고 있다고 생각합니다.

찾고 있는 직사각형을 만드는 데 필요한 것은 경계, 내용 오프셋 및 zoomScale의 조합뿐입니다.

언급URL : https://stackoverflow.com/questions/868288/getting-the-visible-rect-of-an-uiscrollviews-content

반응형