Map UIView subregion to UIScrollView

In my application, I have a large area (β‰ˆ5000x5000pts), and I should allow the user to see (+ scale, scroll) only my specific rectangular subdomain with sides not necessarily parallel to the sides of the area.

What is the best way to do this?

What am I doing now:

  • You have a large UIView containing the entire area (therefore, its frame is 5000x5000) as a UIScrollView subtitle.
  • Calculate and apply CGAffineTransform - rotate my view so that the sides of the area are parallel to the coordinate axis and put the desired area at the origin:

     contentView.transform = CGAffineTransformMake(cos(angle), sin(angle), -sin(angle), cos(angle), -requiredRect.origin.x, -requiredRect.origin.y); 
  • Set the size of the scroll content to the desired value.

     scrollView.contentSize = CGSizeMake(someWidth, someHeight); 

It works in some way, but there are some (not all of the above actually) problems with it:

  • When I zoom in on the scroll, its content size is reset to the size of my large area view (5000x5000 times the zoom factor). I set it again in the scrollViewDidEndZooming delegate scrollViewDidEndZooming , but it still looks weird.
  • Zooming appears to be applied from the wrong anchor point and does not look beautiful (the view β€œjumps” to another position after scaling is complete)

Can you suggest a different approach to the problem or indicate what can be done to improve my current? It seems that UIScrollView is behaving badly when custom transformations are applied to its content views ...

+4
source share
1 answer

Although I'm not completely satisfied with my decision, I came up with the following: in the delegate method -scrollViewDidScroll I check if the current visible region is a subregion of my limited area. If it’s not me, I adjust the content offset without animation to make the visible area suitable for the limits.

 - (void)scrollViewDidScroll:(UIScrollView *)aScrollView{ if (!CGRectContainsRect(myLimitRect, [aScrollView visibleRect]){ // calculate new contents offset to make visible region fit limits [aScrollView setContentOffset:newContentOffset animated:NO}; } } 

This way, I don't need to apply complex CGAffineTransforms in my content view explicitly (no need to scale / translate the view) - all I need to do is rotate it, and it looks like UIScrollView can handle it pretty well.

0
source

Source: https://habr.com/ru/post/1304352/


All Articles