UIScrollView - Prevent UIImageView as subview of UIScrollView from being dragged off screen - iphone

I have a UIImageView element as a subview of my main UIScrollView element.
I want the Image to fill out the whole screen at all times, but I can drag the edges a bit too far, so that the yellow "background" becomes visible.
If I lift my finger, the Image "bounces" back and fills out the screen correctly.
I want to prevent this dragging of the image off screen.
I do however want the image to bounce back once I drag it out of the "safety area".
This is my ScrollView initialization:
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:CGRectMake(0, 0, frame.size.height, frame.size.width)];
if (self) {
[self initImageValues];
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.bouncesZoom = YES;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.delegate = self;
self.backgroundColor = [UIColor yellowColor];
self.minimumZoomScale = 1.0;
self.maximumZoomScale = 2.0;
[self setCanCancelContentTouches:YES];
self.clipsToBounds = YES;
// Load Image
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
[self addSubview:imageView];
[self setContentSize: CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
// Set bigger "bounce" zone (safety area)
self.contentInset=UIEdgeInsetsMake(-SAFETY_ZONE,-SAFETY_ZONE,-SAFETY_ZONE,-SAFETY_ZONE);
self.scrollEnabled = YES;
}
return self;}

Use these delegate methods:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
Then read the offset and return if it's out of the "safety area".
Could be that you need another delegate method from the UIScrollView though, but a workaround like this should fix your problem :)

try setting bounces on the scrollview:
self.bounces = NO;

TRY this:
**
self.scrollView.maximumZoomScale = 1.0;
self.scrollView.minimumZoomScale = 1.0;
**

Try setting its bounces property to NO.

Related

Zooming UIImageView in UIScrollView goes out of bounds

I've successfully implemented zooming of UIImageView in my UIScrollView but I have faced with a strange problem that irritates me.
Basically, when I zoom in the image
I can pan the view to actually scroll out of the image border and I'm left with a black area like this:
And as I zoom in more I can make the black border to fill the whole screen!
Meanwhile in the iPhone Photo app you can't zoom out the actual image. What's wrong here in my implementation?
It looks like this:
UIImage *imageToDisplay = [UIImage imageWithData:tmpImageData];
imageViewMain.image = imageToDisplay;
imageViewMain.frame = CGRectMake(0, 0, scrollViewMain.frame.size.width, scrollViewMain.frame.size.height);
imageViewMain.contentMode = UIViewContentModeScaleAspectFit;
scrollViewMain.delegate = self;
scrollViewMain.minimumZoomScale = 1.0;
scrollViewMain.maximumZoomScale = 9.0;
scrollViewMain.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollViewMain.contentSize = imageViewMain.frame.size;
[self.view addSubview:scrollViewMain];
[scrollViewMain addSubview:imageViewMain];
And I also implement this method:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageViewMain;
}
Thanks in advance!
EDIT:
When I first load the view I shrink my UIImageView to fit the scroll view and the image looks like this:
Just try this code.... change some code where it required... use UIPinchGestureRecognizer for your UIImageView and then add this image in your UIScrollView like bellow..
UIImageView *img = [[UIImageView alloc]init];
img.image = [UIImage imageWithData:tmpImageData];
img.userInteractionEnabled = YES;
img.frame = CGRectMake(210,100, 200, 200);/// define frame which you want...
[img sizeToFit];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[img addGestureRecognizer:pinchRecognizer];
[pinchRecognizer release];
[scrollViewMain addSubview:img];
[scrollViewMain bringSubviewToFront:img];
[img release];
and just paste this bellow code in your .m file...
#pragma mark GestureRecognizer Methods
-(void)scale:(id)sender
{
UIView *imgTempGest = [sender view];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded)
{
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
[imgTempGest setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
Here for LastScale just define that variable in .h file like bellow...
CGFloat lastScale;
i hope this helpful to you...
Is the original image contains that border in top and bottom?. You can use the same code over there the output is not wrong if the actual image contains that black top and bottom black area. And add this code also,
scrollView.scrollEnabled = YES
also change,
scrollView.contentSize = imageView.bounds.size;
Also you are providing a zoom scale of 9. That much is needed for you?. Change it to 3 or 4 and try. Your problem will be fixed

How to zoom in and zoom out mutiple images on scroll view

i have a scroll view with multiple images and i am using this code. i have the images with dimensions (2121 x 2892) in Portrait and (2112 x 1500) in landscape mode
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.pagingEnabled = YES;
scrollView.delegate = self;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.maximumZoomScale = 3.0f;
scrollView.minimumZoomScale = 1.0;
NSInteger numberOfViews = [arrayImages count];
for (int i = 0; i < numberOfViews; i++)
{
CGFloat yOrigin = i * scrollView.frame.size.width;
imageView = [[UIImageView alloc]initWithFrame:CGRectMake(yOrigin +30, 0, self.view.frame.size.width-60 , self.view.frame.size.height)];
imageView.userInteractionEnabled = YES;
imageView.image = [UIImage imageNamed:[arrayImages objectAtIndex:i]];
[scrollView addSubview:imageView];
imageView.userInteractionEnabled = YES;
}
[self.view addSubview:scrollView];
i want to implement the zoomin and zoom out functionality on double tab and moving with two fingers. I saw many sample application but i am not be able to do the same. if anybody have its own code please share with me.
I want to implement the zoomin and zoom out functionality on double tab and moving with two fingers.
For the zoom in on double tap, check out the gesture recogniser part of this tutorial.
As for moving around with 2 fingers, you could use a UIPanGestureRecogniser for 2 touches and change the contentOffset of the scroll view accordingly when a pan is recognised.
simple add a subview to scrollview and add all imageViews in it. and in scrollview's delegate method and do like this
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)inScroll {
return view;
}

iOS - UIScrollView is not working (it doesn't scroll at all - the image stays fixed)

I would like to display an image (width: 320 pixels, height: 1250 pixels) in an image view.
When I compile the application I get no scrolling at all. The view stays fixed.
What I did:
Added an UIScrollView via Interface Builder to my view.
Added an UIImageView via Interface Builder to my view.
Verified that UIImageView is below UIScrollView in Interface Builder.
Set the size of the UIScrollView with ViewDidLoad.
How do I do this?
Code:
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView.contentSize = CGSizeMake(320, 1250);
}
Screenshots:
ImageView:
ScrollView:
I just have done the same task..
Try this one.....
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
int scrollWidth = 120;
scrollView.contentSize = CGSizeMake(scrollWidth,80);
int xOffset = 0;
imageView.image = [UIImage imageNamed:[imagesName objectAtIndex:0]];
for(int index=0; index < [imagesName count]; index++)
{
UIImageView *img = [[UIImageView alloc] init];
img.bounds = CGRectMake(10, 10, 50, 50);
img.frame = CGRectMake(5+xOffset, 0, 50, 50);
NSLog(#"image: %#",[imagesName objectAtIndex:index]);
img.image = [UIImage imageNamed:[imagesName objectAtIndex:index]];
[images insertObject:img atIndex:index];
scrollView.contentSize = CGSizeMake(scrollWidth+xOffset,110);
[scrollView addSubview:[images objectAtIndex:index]];
xOffset += 70;
}
Also set this one....
imagesName = [[NSArray alloc]initWithObjects:#"image1.jpg",#"image2.jpg",#"image3.jpg",#"image4.jpg",#"image5.jpg",#"image6.png",#"image7.png",#"image9.png",nil];
images = [[NSMutableArray alloc]init];
So for me the problem was that setting the content size didn't work in viewDidLoad(). I tried everything and I didn't understand why it wouldn't want to work, and then I tried the same stuff in viewDidAppear() and it magically worked...
From you last screenshot and from your comments it looks like your scrollView is way to big.
The scrollview must be visible on screen completely. For example a full screen UIScrollView on iPhone would have a size of 320 x 460.
If the scrollview is the same size as its content you can't scroll.
The greenish rectangle shows the size of your scrollview, the pinkish the size of your content (your image):
Xcode 11+, Swift 5
You can find the complete solution here.
I came across this same issue on iOS6 and the solution was to programmatically adjust the ContentSize.
So I will just quote from Raja (above) to show this:
CGSize scrollViewContentSize = CGSizeMake(320, 400);
[self.scrollView setContentSize:scrollViewContentSize];
NOTE: I was not having this issue on iOS5.. seems like iOS6 decided to do alot of prank just like the rotation/orientation saga
Since Xcode 5 it does not work like before. Also scrolling to the end of a scrollable text field makes problems. There are also differences between doing it on iPhone or iPad. On iPhone it worked without delayed timer.
This worked for me:
- (void)viewDidLoad
{
[super viewDidLoad];
NSTimer *timerforScrollView;
timerforScrollView =[NSTimer scheduledTimerWithTimeInterval:0.1
target:self selector:#selector(forScrollView)userInfo:nil repeats:NO];
}
- (void) forScrollView {
[scrollviewPad setScrollEnabled:YES];
[scrollviewPad setContentSize:CGSizeMake(768, 1015)]; // must be greater then the size in Storyboard
}
I found I had a similar problem but none of the above code worked. The issue was due to autolayout. I found that if I turned off autolayout by going to the storyboard clicking on Utilities -> File Inspector and unchecked Use Autolayout the scrolling did work (I also set scroll.contentSize = ...).
Sometimes autoLayout checkbox is ticked in the xib. That also creates this issue in xcode 5. Which makes the UIScrollView scrolling off.
Don't forget to add the category protocol to the interface, like this
#interface MyViewController : <UIScrollViewDelegate>
If you don't, you will not be able to set the scroll view delegate to self
(i.e. [MyScrollView setDelegate:self];)
If you do this, it should work.
My code is:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[contentScrollView setDelegate:self];
[contentScrollView setScrollEnabled:YES];
contentScrollView.contentSize = CGSizeMake(310, 500);
contentScrollView.frame = CGRectMake(5, 188, 310, 193);
}
Did you assign the scroll's view delegate? Always remember these:
[self.scrollView setDelegate:self];
[self.scrollView setScrollEnabled:YES];
The image view has to be a subview (so inside AND below) of the scrollview. From your description it seems they are paralell
You forgot one line. Add this to your view load function:
[scrollView setScrollEnabled:YES];
You could try disabling AutoLayout. In XCode 5 I tested all the above answers and I could only scroll it by disabling autolayout and activating all autosizing masks under the Size Inspector. The following code was used too:
self.scrollView.contentSize = CGSizeMake(320, 900);
self.scrollView.delegate = self;
self.scrollView.scrollEnabled = YES;
self.scrollView.frame = self.view.frame;
CGRect scrollViewFrame = CGRectMake(0, 0, 320, 400);
self.scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
[self.view addSubview:self.scrollView];
CGSize scrollViewContentSize = CGSizeMake(320, 400);
[self.scrollView setContentSize:scrollViewContentSize];
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (image == nil) {
break;
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = image.size.height;
rect.size.width = image.size.width;
rect.origin.x = ((scrollView.frame.size.width - image.size.width) / 2) + cx;
rect.origin.y = ((scrollView.frame.size.height - image.size.height) / 2);
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += scrollView.frame.size.width;
}
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
Assuming that scrollView is a subview of view and fills it entirely you can use the following in viewDidLoad:
[scrollView setContentSize: CGSizeMake(self.view.frame.size.width, self.view.frame.size.height)];
I had a UIScrollView that was not scrolling and this allowed it to scroll.
Just add code
scrollView.contentSize = CGSizeMake(WIDTH,HEIGHT);
to method -(void)viewDidLayoutSubviews.
For more information checkout Stanford CS193p Lecture No 8 to understand View Controller Life cycle.
I had the same issue and was looking for the answer in this thread. I tried all the stuff, but nothing works. Then I found this:
.
You just need to deselect "Use Auto Layout" in File Inspector of your ViewController. Ta-Da, it works immediately for me. Enjoy.

How Can I Move An UIImageView Around In A UIScrollView?

In my application, I have a UIImageView inside a UIScrollView. I want to zoom and drag the UIImageView. I managed to do the zooming but I can't seem to find a way to drag the image inside the UIScrollView using touchesMoved. I have Googled around but it seems that the only method I have found was only possible in iOS 3.0+ but is now obsolete in iOS 4.0+. So how can I drag an image with my finger that is inside a UIScrollView?
You shouldn't need to do any touch detection yourself. UIScrollView can take care of everything.
Here's a example:
- (void)viewDidLoad
{
[super viewDidLoad];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.delegate = self;
[self.view addSubview:scrollView];
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.jpg"]];
scrollView.contentSize = imageView.bounds.size;
[scrollView addSubview:imageView];
float minScale = scrollView.frame.size.width / imageView.frame.size.width;
scrollView.minimumZoomScale = minScale;
scrollView.maximumZoomScale = 2.0;
scrollView.zoomScale = minScale;
}
Don't forget to add this delegate method to enable zooming:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}

iphone uiscrollview and uiimageview - setting initial zoom

I use the following code to load an image into an scroll view. The image always loads at 100% zoom. Is there a way to set it to load to another zoom level, say .37?
I have tried scrollView.zoomScale = .37 but it didnt seem to work
UIImageView *tempImage = [[UIImageView alloc]initWithImage:[UIImage imageWithData:data]];
self.imageView = tempImage;
scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
scrollView.maximumZoomScale = 1;
scrollView.minimumZoomScale = .37;
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
Zooming only works when you implement the viewForZoomingInScrollView: delegate callback.
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)inScroll {
return imageView;
}
I figured it out... I was using scrollView.zoomScale = 0.37; before I loaded the image changed code and it works great.
UIImageView *tempImage = [[UIImageView alloc]initWithImage:[UIImage imageWithData:data]];
self.imageView = tempImage;
scrollView.contentSize = CGSizeMake(imageView.frame.size.width , imageView.frame.size.height);
scrollView.maximumZoomScale = 1;
scrollView.minimumZoomScale = .37;
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
scrollView.zoomScale = .37;
There is a zoomScale property that you can set.
I was facing same issue..
i used the built in method : scrollViewForImage
This will set the initial zoom to level 5
[self.scrollViewForImage setZoomScale:5 animated:YES];
code for minimum zoom level
self.scrollViewForImage.minimumZoomScale=1;
code for Maximum Zoom Level
self.scrollViewForImage.maximumZoomScale=12.0;
Hope this will help
You must set the initial zoom when the viewwillappear and not when the viewdidload for it too work.