Make 2 UIScrollViews zoom and scroll identically - ios

I have a screen which has two UIScrollViews. Inside the scrollview is a zoomable UIImageView.
I'd like to achieve the same scrolling and zooming inside one scrollView to be applied to the other one. i.e. if the user pans across the image, both scrollviews pan their images at the exact same rate. If the user pinch zooms the image in one, the other zooms exactly the same amount.
I've read on here about using the zoomToRect:animated: call. I'm not sure exactly how to implement that, so I've tried the following - but it doesn't seem to yield the right results. NB. the scrollView contain self.imageViewLeft. self.scrollViewRight is the scrollView not being touched.
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:self.imageViewLeft];
[self.scrollViewRight zoomToRect:visibleRect animated:false];
}

I solved it guys! Props to me.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.scrollViewLeft) {
[self.scrollViewRight setZoomScale:[scrollView zoomScale]];
[self.scrollViewRight setContentOffset:[scrollView contentOffset]];
} else {
[self.scrollViewLeft setZoomScale:[scrollView zoomScale]];
[self.scrollViewLeft setContentOffset:[scrollView contentOffset]];
}
}

Related

UIScrollView zoom auto

As many others, i am trying to implement a zooming behavior with the UIScrollView. I am using Auto Layout to layout my subviews.
In IB i have:
ScrollView
ImageView
The imageView has constraints to fill up the entire scrollView, so the image will be displayed in it's full size on load. This works like a charm. However, i cannot, for the life of me, figure out how to enable zooming. So far i have this code:
[_imgViewInScroll setImage:trackImg];
_scrImageViewer.scrollEnabled = YES;
_scrImageViewer.delegate = self;
_scrImageViewer.contentSize = trackImg.size;
_scrImageViewer.minimumZoomScale = 1;
_scrImageViewer.maximumZoomScale = 4;
And the implemented protocol:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog(#"Zooming");
return imgView;
}
But it doesn't work. The image is displayed, in full size filling the entire screen on load as expected, but it just won't respond to zooming at all. The NSLog statement gets executed, so it takes in the zooming request, but doesn't zoom.
What can i do? Thanks in advance.
I think you are returning the wrong imageview name. Replace "imgView" by "_imgViewInScroll".
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog(#"Zooming");
return _imgViewInScroll;
}

How to trick UIScrollView into starting scrolling in the middle of panning?

Example:
You have a UIScrollView with scrollEnabled = NO.
After user pans a certain distance, you want the scroll view to start scrolling.
When finger goes down on screen and I disable scrolling, the scroll view is dead until the finger is lifted. Enabling scrolling in middle of a pan doesn't cause it to start.
I suspect it is because UIScrollView will decide to ignore the touch sequence if it was scrollEnabled=NO during its internal touchesBegan:withEvent: (or its private pan gesture recognizer).
How would you trick it into starting to scroll natively (with bounce effect) in the middle of a touch sequence?
Reason: For a simple UIKit based game that requires this mechanic.
Okay, this still needs a little bit of tweaking to handle scrolling again after the first scroll has stopped, but I think the key to what you're trying to achieve is to implement the UIScrollViewDelegate method scrollViewDidScroll:. From here, you can save the starting content offset of the scroll view, and compare the scroll view's current offset to the starting offset added to the y translation of the scroll view's pan gesture recognizer.
The code below successfully doesn't allow scrolling to start until the user has panned at least 100 pts. Like I said, this needs a little tweaking, but should be enough to get you going.
- (void)viewDidLoad
{
[super viewDidLoad];
[self setStartingOffset:CGPointMake(0.0, -1.0)];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (self.startingOffset.y < 0.0) {
[self setStartingOffset:scrollView.contentOffset];
}else{
static CGFloat min = 100.0;
CGFloat yTranslation = fabs([scrollView.panGestureRecognizer translationInView:scrollView].y);
if (yTranslation < self.startingOffset.y + min) {
[scrollView setContentOffset:self.startingOffset];
}else{
if (self.startingOffset.y >= 0.0) {
[self setStartingOffset:CGPointMake(0.0, -1.0)];
}
}
}
}

UIScrollView events for scrolling that definitely occurred

I am working with aUIScrollview, and based on if the user scrolls left or right, I reconfigure the UI. The problem is that I need to verify that the user definitely crossed from one screen to another (something along contentOffset).
I've tried using this method:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
But this will fire if the user kind of moves the scrollview partially in one direction, but then doesn't complete the gesture.
I've also tried this method:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView;
but mainly the same issue; the scrollview scrolls left and right, but on an iPhone, with a content with of 640 ( 320 * 2). I am trying to figure out if the scroll did cross over or not, from one location to the other.
Any suggestions?
I am not entirely sure what you mean by "crossed from one screen to another" I assume you mean paging? If so, here's what you can do:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
int page = sender.contentOffset.x / width;
[self.pageControl setCurrentPage:page]; // in case you need it for updating a UIPageControl
}
I found a way of doing this :
I have a variable to maintain the x location of the contentOffset
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
currX = self.scrollView.contentOffset.x;
}
And then in this event :
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if(self.scrollView.contentOffset.x == currX ) {
return;//This is what I needed, If I haven't panned to another view return
}
//Here I do my thing.

Subview Gesture recognition issues while on scaling/scrolling view that is not at 1:1

I have a UIScrollView that on it I have also created Gesture Recognizers. Tap, Double Tap, two finger tap, etc. On the Scroll View I create several other UIViews. Think of each of these views as Drawing objects. Circle, Squares, buttons, images, etc. Each of the Subviews I can pan, rotate, tap, etc and they all work for the most part.
If the Scaling Scroll View is not at 100% (1-1) then panning the subviews gets a bit sketchy. you can always tap them to get them to Highlight, though panning, rotation, etc is iffy. Typically if I try to pan a selected subview, it pans the scroll view. Sometimes it works, sometimes it does not. Set the zoom to 100%, or turn off the Scrolling (set scale to the same min/max), I can do what Is expected.
Any Suggestions on where to start troubleshooting this?
Not 100% why this works, but this is the code that made the issue disappear. I had to Subclass UIScrollView, override (BOOL)touchesShouldCancelInContentView:(UIView *)view and return NO if the view was anything but the UIView class for the UIScrollView.View
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
BOOL returnVal = NO;
if ([view isKindOfClass:[IoScreenEditorContentView class]]) {
returnVal = [super touchesShouldCancelInContentView:view];
}
return returnVal;
}

UIScrollView : only paging horizontally left, bouncing right

How can I force a UIScrollView in which paging and scrolling are on to only move horizontally left or horizontally both direction(left and right)?
To be clearer, I'd like to allow the user to 'page only horizontally backward(only bounce when the user try to scroll horizontally right)' OR 'horizontally both direction(this is normal action)' at a given moment.
I am wondering that the solution is the subclass of UIScrollView.
Thanks in advance.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ( only bounce.. ){
// is it right?
if (scrollView.contentOffset.y > 60) {
[scrollView setContentOffset:CGPointMake(0, 60)];
}
}
if ( only paing left... ){
How to do this??
}
}
I'd implement the delegate function scrollViewDidScroll: and store the state (scroll state) of the ScrollView. On subsequent calls, compare with the previous state and have it bounce back (by calling ZoomToRect: maybe) if it is in a particular direction that you don't like.

Resources