I have a problem with a scrollView zooming the wrong imageView - iphone

Ok so this is kind of a strange issue, but I have got two scrollViews that each have a nested imageView so as to allow for panning and zooming of an image. The tow scrollView/imageView combo's are showing up just great, and because the image is bigger than my scrollView size, I can pan just great. Here is my viewDidLoad:
-(void) viewDidLoad
{
// set the image to be displayed, pic your own image here
imageView = [[MyImage alloc] initWithImage: [UIImage imageNamed: #"newBackground.png"]];
// yes we want to allow user interaction
[imageView setUserInteractionEnabled:YES];
// set the instance of our myScrollView to use the main screen
scrollView = [[MyScroll alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
// turn on scrolling
[scrollView setScrollEnabled: YES];
// set the content size to the size of the image
[scrollView setContentSize: imageView.image.size];
// add the instance of our myImageView class to the content view
[scrollView addSubview: imageView];
// flush the item
[imageView release];
// set max zoom to what suits you
[scrollView setMaximumZoomScale:1.0f];
// set min zoom to what suits you
[scrollView setMinimumZoomScale:0.25f];
// set the delegate
[scrollView setDelegate: self];
// scroll a portion of image into view (my image is very big) :)
//[scrollView scrollRectToVisible:CGRectMake(100, 100, 320, 440) animated:NO];
// yes to autoresize
scrollView.autoresizesSubviews = YES;
// set the mask
scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
// set the view
//self.view =scrollView;
[scrollView setFrame:CGRectMake(0, 0, 320, 230)];
[self.view addSubview:scrollView];
imageView1 = [[MyImage alloc] initWithImage: [UIImage imageNamed: #"newBackground.png"]];
// yes we want to allow user interaction
[imageView1 setUserInteractionEnabled:YES];
// set the instance of our myScrollView to use the main screen
scrollView1 = [[MyScroll alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
// turn on scrolling
[scrollView1 setScrollEnabled: YES];
// set the content size to the size of the image
[scrollView1 setContentSize: imageView1.image.size];
// add the instance of our myImageView class to the content view
[scrollView1 addSubview: imageView1];
// flush the item
[imageView1 release];
// set max zoom to what suits you
[scrollView1 setMaximumZoomScale:1.0f];
// set min zoom to what suits you
[scrollView1 setMinimumZoomScale:0.25f];
// set the delegate
[scrollView1 setDelegate: self];
// scroll a portion of image into view (my image is very big) :)
//[scrollView scrollRectToVisible:CGRectMake(100, 100, 320, 440) animated:NO];
// yes to autoresize
scrollView1.autoresizesSubviews = YES;
// set the mask
scrollView1.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
// set the view
//self.view =scrollView;
[scrollView1 setFrame:CGRectMake(0,240,320,230)];
[self.view addSubview:scrollView1];
//[[self view] addSubview:scrollView];
}
No as for zooming, when I pinch to zoom on the FIRST scrollView/imageView pair, it works beautifully, no problems whatsoever. It zooms and pans no problem. BUT when I pinch to zoom my second scrollView, it pans the image of the SECOND, and zooms the image of the FIRST. SO my SECOND scrollView zooms the FIRST's image. Huh? I have no idea why that would be happening.
All I want is to have to separate images viewed that can be independently panned and zoomed.
Any thoughts as to what might be happening?
Thanks!

Your viewForZoomingInScrollView: method is probably returning the same image view for both scroll views. It needs to look at which scroll view is being passed in and return the corresponding image view.

Related

UIScrollview ContentSize magic

I am zooming an UIImageView in a UIScrollView on double tap. Works fine when it is set up in Interface Builder. The magic that I see here is, the contentSize of the scrollView increses/decreases by itself as I zoom in/out. I check for the contentSize in viewDidLoad, its not zero.
I tried the same by removiing the scrollView and imageView from IB and created them programmatically. After adding the imageView and tapGestureRecognizer, I fail to zoom here. When I checked for the reason, the contentSize remains zero everywhere.
When I add them in IB/xib, I am doing nothing with the contentSize. I am not setting it anywhere. I find its woking fine, the contentSize adjusts automatically where I need. But, its is not replicating when I create the scrollView programmatically.
How Can I make it work? I welcome your suggestions.
Here is my code for the reference.
ScrollView created in IB
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[imageView addGestureRecognizer:doubleTap];
imageScrollView.minimumZoomScale=1.01;
imageScrollView.maximumZoomScale=5;
imageScrollView.zoomScale=1.01;
NSLog(#"height = %f width = %f", imageScrollView.contentSize.height, imageScrollView.contentSize.width);
}
NSLog says
height = 449.479767 width = 320.000000
ScrollView created programmatically
- (void)viewDidLoad {
[super viewDidLoad];
imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[imageView addGestureRecognizer:doubleTap];
imageScrollView.minimumZoomScale=1.01;
imageScrollView.maximumZoomScale=5;
imageScrollView.zoomScale=1.01;
[self.view addSubview:imageScrollView];
[self.imageScrollView addSubview:imageView];
NSLog(#"height = %f width = %f", imageScrollView.contentSize.height, imageScrollView.contentSize.width);
}
NSLog says
height = 0.000000 width = 0.000000
These properties
self.minimumZoomScale=1.01;
self.maximumZoomScale=5;
self.zoomScale=1.01;
should be properties of your scrollView:
imageScrollView.minimumZoomScale=1.01;
imageScrollView.maximumZoomScale=5;
imageScrollView.zoomScale=1.01;
Then additionally you need to set the contentSize property (when using IB you don't need to set it as it is loaded from the xib file):
imageScrollView.contentSize = CGSizeMake(width,height);
using appropriate values.
Additionally you need to set the delegate:
imageScrollView.delegate = self;
And at least one delegate method indicating which subview to zoom:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return scrollView.subviews[0];
}
(actually you are better off setting a tag on the subview or assigning it to a property to get a reference to it, as scrollViews also have built-in subviews)
Is auto layout enabled in your xib? If so, IB is setting up constraints betwixt the image view and the scroll view, and at runtime auto layout uses the constraints to set the scroll view's content size. When you create the views in code, you're not adding enough constraints and not setting the content size directly, so the content size remains zero.
Read Tech note TN2154 for more information.
The similar answer is given by #Pheel about the zooming of image inside a scrollview using coding.
The link of the answer is given below:
IOS: add imageview in a scrollview to have zoom

uiimageview aspectfit question

I've use a imagepicker to select image from my photo library, then i display that image in an uiimageview. Landscape photo works fine but there is some weirdness to the portrait image. The portrait image suppose to fill up the left and right empty space but it's not.
Cant figure out why the picture wont fill up the left and right space cause the imageview frame did specify the mainScreen bounds.
If i take away the aspectfit then the potrait image is nicely display but the landscape image is stretched to fill up the whole imageview.
My code is as follow:
CGRect frame = [[UIScreen mainScreen] bounds];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:frame];
UIImageView *selectedImageView = [[UIImageView alloc] initWithFrame:frame];
selectedImageView.image = image;
selectedImageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubview:selectedImageView];
[selectedImageView release];
scrollView.delegate = self;
[self.view addSubview:scrollView];
[scrollView release];
Here is what it looks like:
Edit: My goal is to display the photo like it's been display in Photos album, start out as fitting in the view and allow zoom in to a certain limit.
Try out
UIImageView *logoImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo_bg.png"]];
[logoImageView setFrame:CGRectMake(0, 0, 320, [UIImage imageNamed:#"logo_bg.png"].size.height)];
[mainView addSubview:logoImageView];

How to implement two separate UIScrollViews with nested UIImageViews...only one is zooming

Ok, I have been working on solving this problem all day, and I am getting really close. I am trying to have create a way to view more than one scrollView/imageView nested pair that allows for zooming on an image.
When the view loads, there is just one scrollView that takes up the whole screen, but then when a button is pressed, I cut the width of the first scrollView in half, and unhide another (which has a nested imageView in it as well) right next to it. So there is a split view effect, and ideally the user will be able to pinch and zoom each image separately.
So I have all that working except for the separate pinch and zoom part. No matter where I pinch on the screen, only the first scrollView zooms. So even though I am touching another scrollView, it is still only affecting the first.
I have them setup in IB, and then they are setup in viewDidLoad this way:
[scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.minimumZoomScale = 1;
scrollView.maximumZoomScale = 5;
scrollView.delegate = self;
[scrollView setScrollEnabled:YES];
imageView3 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"monitor.JPG"]];
[scrollView addSubview:imageView3];
//[scrollView setFrame:CGRectMake(0, 0, 1024, 660)];
[scrollView1 setBackgroundColor:[UIColor blackColor]];
[scrollView1 setCanCancelContentTouches:NO];
scrollView1.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView1.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView1.minimumZoomScale = 1;
scrollView1.maximumZoomScale = 5;
scrollView1.delegate = self;
[scrollView1 setScrollEnabled:YES];
imageView31 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"monitor.JPG"]];
[scrollView1 addSubview:imageView31];
And then I hide and unhide different scrollViews (I have 40 depending on the segmentedControl index on the toolbar. Am I headed in the right direction? Is it possible to have two separately accessible scrollViews?
Any help would be appreciated.
Thanks!
EDIT:
Ok so I went through and updated the clipToBunds bit...DUH. It definitely makes it look better, but still isn't solving the problem. Here is the code I am calling depending on the selected index:
-(void) pickedOne{
if(segment.selectedSegmentIndex == 0){
[scrollView setFrame:CGRectMake(0, 0, 1024, 660)];
[scrollView setContentSize:CGSizeMake(1024, 660)];
scrollView.hidden = NO;
scrollView1.hidden = YES;
scrollView2.hidden = YES;
scrollView3.hidden = YES;
}else if(segment.selectedSegmentIndex == 1){
[scrollView setFrame:CGRectMake(0, 0, 512, 660)];
scrollView.zoomScale = 1.0;
scrollView.hidden = NO;
[scrollView1 setFrame:CGRectMake(512, 0, 512, 660)];
scrollView1.zoomScale = 1.0;
scrollView1.hidden = NO;
scrollView2.hidden = YES;
scrollView3.hidden = YES;
}
Is there anything majorly wrong with that approach?
If I pinch to zoom on the right scrollView, it makes the scroll view bigger, (but doesn't increase the size of the scrollView2 image) but it DOES increase the size of the first scrollView's image when you pinch inside of EITHER scrollViews...strange
scrollView.clipsToBounds = NO; // default is NO, we want to restrict drawing within our scrollview
Isn't this the opposite of what you want? Setting it to YES restricts restricts drawing to within your scrollview.
It sounds to me like you aren't resizing the scrollview. Are you resizing its contents or the image view within it? Can you post the code that is called when you tap the button?

I would like to have two zoomable UIImageViews...on the same view, but I can't get it to work!

Ok I have been working on this feature for some time now and it is driving me nuts. I have looked all around the web and can't seem to find any answer. I want to have a view that has two UIScrollviews, that themselves contain a UIImageView each. So I can have to images on my view that are SEPARATELY scroll/zoomable.
It seems pretty simple, but I just can't get it to work. I setup the ScrollView/ImageView pairs in IB and hooked them up ok. Now my viewDidLoad code looks like this:
-(void) viewDidLoad
{
// set the image to be displayed, pic your own image here
imageView = [[MyImage alloc] initWithImage: [UIImage imageNamed: #"newBackground.png"]];
// yes we want to allow user interaction
[imageView setUserInteractionEnabled:YES];
// set the instance of our myScrollView to use the main screen
scrollView = [[MyScroll alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
// turn on scrolling
[scrollView setScrollEnabled: YES];
// set the content size to the size of the image
[scrollView setContentSize: imageView.image.size];
// add the instance of our myImageView class to the content view
[scrollView addSubview: imageView];
// flush the item
[imageView release];
// set max zoom to what suits you
[scrollView setMaximumZoomScale:1.0f];
// set min zoom to what suits you
[scrollView setMinimumZoomScale:0.25f];
// set the delegate
[scrollView setDelegate: self];
// scroll a portion of image into view (my image is very big) :)
//[scrollView scrollRectToVisible:CGRectMake(100, 100, 320, 440) animated:NO];
// yes to autoresize
scrollView.autoresizesSubviews = YES;
// set the mask
scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
// set the view
//self.view =scrollView;
[scrollView setFrame:CGRectMake(0, 0, 320, 240)];
self.view =scrollView;
imageView1 = [[MyImage alloc] initWithImage: [UIImage imageNamed: #"newBackground.png"]];
// yes we want to allow user interaction
[imageView1 setUserInteractionEnabled:YES];
// set the instance of our myScrollView to use the main screen
scrollView1 = [[MyScroll alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
// turn on scrolling
[scrollView1 setScrollEnabled: YES];
// set the content size to the size of the image
[scrollView1 setContentSize: imageView1.image.size];
// add the instance of our myImageView class to the content view
[scrollView1 addSubview: imageView1];
// flush the item
[imageView1 release];
// set max zoom to what suits you
[scrollView1 setMaximumZoomScale:1.0f];
// set min zoom to what suits you
[scrollView1 setMinimumZoomScale:0.25f];
// set the delegate
[scrollView1 setDelegate: self];
// scroll a portion of image into view (my image is very big) :)
//[scrollView scrollRectToVisible:CGRectMake(100, 100, 320, 440) animated:NO];
// yes to autoresize
scrollView1.autoresizesSubviews = YES;
// set the mask
scrollView1.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
// set the view
//self.view =scrollView;
[scrollView1 setFrame:CGRectMake(0, 300, 320, 220)];
//I do this only because I don't know what else to do. This effectively adds the scrollview to the scrollview...
self.view =scrollView1;
And the first scrollView loads, but then the second one is nested in that one! I tried doing[self.view addSubView:scrollView1]; but that just made the app crash. I'm trying my best to really dig in and figure out scrollViews as best I can, but I am just getting owned here.
Please help!
Thanks
** To further clarify, all I want is to have a scrollView on the top half of an image that can pan and zoom with an image inside of it, and then another scrollView separate from the firt that can pan and zoom on the bottom half of the screen, independent of the first.**
You need to add both scroll views as subviews of the ViewController's view (self.view):
[self.view addSubview:scrollView];
[self.view addSubview:scrollView1];
You'll then need to manually position those views so they're positioned like you want them (the above code will put the two scroll views on top of each other, with some arbitrary default size which may or may not be what you want).

UIScrollView and image thumbnails

I want to have a scroll view, where you display 5 thumbnails on the scroll view each time.
Basically it's a table with one row and in each row we have 5 thumbnails in it.
You slide your finger to the right then you display the next set of 5 thumbnails.
What do I need to do this?? Is it true that we need a scroll view to do this? How can I start?
In your UIView that will contain your UIScrollView, place (something like) this code in -viewDidLoad:
UIScreen *screen = [UIScreen mainScreen];
pageWidth = screen.bounds.size.height;
pageHeight = screen.bounds.size.width;
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, pageWidth, pageHeight)];
[scrollView setAutoresizingMask:UIViewAutoresizingNone];
[scrollView setContentSize:CGSizeMake(numPages * pageWidth, pageHeight)];
[scrollView setContentOffset:CGPointMake(pageWidth, 0)];
[scrollView setPagingEnabled:YES];
[scrollView setDelaysContentTouches:YES];
[scrollView setDelegate:self];
[scrollView setClearsContextBeforeDrawing:NO];
[scrollView setOpaque:YES];
[self.view insertSubview:scrollView atIndex:0];
[scrollView release];
// iterate through your thumbnails - which are UIViews
thumbnailViews = [NSMutableArray array];
[thumbnailViews retain];
NSUInteger pageCounter = 0;
for (...)
{
ThumbnailView *thumbnailView = [[ThumbnailView alloc] initWithFrame:CGRectMake( pageCounter*pageWidth, 0, pageWidth, pageHeight )];
[thumbnailView setMultipleTouchEnabled:YES];
[thumbnailView setViewController:self]; // this may be necessary to push/pop on navigation controller stack.
[thumbnailView restoreState];
[scrollView thumbnailView];
[thumbnailViews thumbnailView];
++pageCounter;
}
In my case, pageWidth, pageHeight, thumbnailViews and scrollView are all ivars for my UIView subclass.
I just looked in here as I'm learning about UIScrollViews myself. I started to try and get westsider's code to work, but I noticed that it is practically gobblygook. It should be in a UIViewController that implements the <UIScrollViewDelegate> protocol, and things like [scrollView thumbnailView]; is meaningless as here thumbnailView is a method name. I believe http://www.codeproject.com/Articles/46556/How-To-Use-UIScrollView-in-Your-iPhone-App.aspx is more coherent.
To answer the question, I think you want to create a UIScrollView in a standard manner--such as in the link, and you want to create a subclass of UIView called, say, UIView5 that has 5 UIImageViews. Then, instead of adding a normal UIView to the UIScrollView, like [scrollView addSubview:standardUIView];, you add UIView5 objects.