Do I actually need a UIPinchGestureRecognizer inside a UIScrollView to have the pinch working? If yes how do I do it? I am trying to implement what flipboard has, where it b
I did a custom image viewer not a long ago without the pinch recognizers. Just UIImageView on top of UIScrollView. There you pass a string with a link to the image and it also has a progress bar. Once that image is finished loading the image is shown. Here's the code:
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.theImageView;
}
- (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {
CGSize boundsSize = scroll.bounds.size;
CGRect frameToCenter = rView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width) {
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
}
else {
frameToCenter.origin.x = 0;
}
// center vertically
if (frameToCenter.size.height < boundsSize.height) {
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
}
else {
frameToCenter.origin.y = 0;
}
return frameToCenter;
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
self.theImageView.frame = [self centeredFrameForScrollView:self.theScrollView andUIView:self.theImageView];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.resourceData setLength:0];
self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.resourceData appendData:data];
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
self.progressBar.progress = [resourceLength floatValue] / [self.filesize floatValue];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
self.theImage = [[UIImage alloc]initWithData:resourceData];
self.theImageView.frame = CGRectMake(0, 0, self.theImage.size.width, self.theImage.size.height);
self.theImageView.image = self.theImage;
self.theScrollView.minimumZoomScale = self.theScrollView.frame.size.width / self.theImageView.frame.size.width;
self.theScrollView.maximumZoomScale = 2.0;
[self.theScrollView setZoomScale:self.theScrollView.minimumZoomScale];
self.theScrollView.contentSize = self.theImageView.frame.size;
self.theLabel.hidden = YES;
self.progressBar.hidden = YES;
}
-(void)setImageInImageView
{
NSURLRequest *req = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:self.imageLink]];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:req delegate:self];
if (conn)
{
self.resourceData = [NSMutableData data];
}
else
{
NSLog(@"Connection failed: IMageViewerViewController");
}
}
-(void)loadView
{
self.filesize = [[NSNumber alloc]init];
self.progressBar = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
self.progressBar.frame = CGRectMake(20, 240, 280, 40);
[self.progressBar setProgress:0.0];
self.theImageView = [[[UIImageView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
self.theScrollView = [[[UIScrollView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
self.theScrollView.delegate = self;
[self.theScrollView addSubview:self.theImageView];
self.view = self.theScrollView;
self.theLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 320, 40)];
self.theLabel.font = [UIFont boldSystemFontOfSize:15.0f];
self.theLabel.text = @"Please wait, file is being downloaded";
self.theLabel.textAlignment = UITextAlignmentCenter;
self.theLabel.hidden = NO;
[self.view addSubview:self.progressBar];
[self.view bringSubviewToFront:self.progressBar];
[self.view addSubview:self.theLabel];
[self.view bringSubviewToFront:self. theLabel];
[self performSelectorOnMainThread:@selector(setImageInImageView) withObject:nil waitUntilDone:NO];
}
And the header file:
@interface ImageViewerViewController : UIViewController<UIScrollViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate>
@property (nonatomic, retain) IBOutlet UIImageView *theImageView;
@property (nonatomic, retain) IBOutlet UIScrollView *theScrollView;
@property (nonatomic, retain) NSString *imageLink;
@property (nonatomic, retain) UIImage *theImage;
@property (nonatomic, retain) UILabel *theLabel;
@property (nonatomic, retain) UIProgressView *progressBar;
@property (nonatomic, retain) NSMutableData *resourceData;
@property (nonatomic, retain) NSNumber *filesize;
@end
Hope it helps
Objective C
Pinch-zoom Image in Scrollview Steps (Objective C)
1. Scroll View Constraints
2. Add ImageView In ScrollView and set Constraints
3. Take IBOutlets
IBOutlet UIScrollView * bgScrollView;
IBOutlet UIImageView * imageViewOutlet;
4. viewDidLoad Method
- (void)viewDidLoad
{
[super viewDidLoad];
float minScale=bgScrollView.frame.size.width / imageViewOutlet.frame.size.width;
bgScrollView.minimumZoomScale = minScale;
bgScrollView.maximumZoomScale = 3.0;
bgScrollView.contentSize = imageViewOutlet.frame.size;
bgScrollView.delegate = self;
}
5. Scroll View Delegate Method
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageViewOutlet;
}
Swift
Pinch-zoom Image in Scrollview Steps (Swift)
1. Scroll View Constraints
2. Add ImageView In ScrollView and set Constraints
3. Take IBOutlets
@IBOutlet weak var bgScrollView : UIScrollView!
@IBOutlet weak var imageView : UIImageView!
4. viewDidLoad Method
override func viewDidLoad() {
super.viewDidLoad()
let minScale = bgScrollView.frame.size.width / imageView.frame.size.width;
bgScrollView.minimumZoomScale = minScale
bgScrollView.maximumZoomScale = 3.0
bgScrollView.contentSize = imageView.frame.size
bgScrollView.delegate = self
}
5. Scroll View Delegate Method
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
All you need to do is add your UIImageView
(or any view you want to zoom) inside your UIScrollView
.
Set your maximumZoomScale
on your UIScrollView
to any value higher than 1.0f.
Set yourself as the delegate of your UIScrollView
and return the UIImageView
in the viewForZooming delegate method.
That's it. No pinch gesture needed, no nothing. UIScrollView
handles pinch zooming for you.
I guess this answer may be unnecessary but I have had similar problems as @adit and solved it in a very simple way (I think) and maybe someone with similar challenges can use it:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
UIImage *imageToLoad = [UIImage imageNamed:@"background_green"];
self.myImageView = [[UIImageView alloc]initWithImage:imageToLoad];
self.myScrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
[self.myScrollView addSubview:self.myImageView];
self.myScrollView.contentSize = self.myImageView.bounds.size;
self.myScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
self.myScrollView.minimumZoomScale = 0.3f;
self.myScrollView.maximumZoomScale = 3.0f;
self.myScrollView.delegate = self;
[self.view addSubview:self.myScrollView];
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
NSLog(@"viewForZoomingInScrollView");
return self.myImageView;
}
My problem was a very simple I had forgot to add self.myScrollView.delegate = self;
, which was the reason why i had problems. It took me forever to figure that simple problem out, i guess I did not see the forrest for all the trees :-)
For 'snap-image-to-screen-edges' solution @Shrikant Tanwade's worked well, but I wanted some insets. I tried settings constraints' constants, but that does not worked.
I ended with following solution:
same as for Shrikant's - set scrollView
, imageView
's constraints, set their constants to 0
.
set insets with scrollView.contentInset = UIEdgeInsetsMake(....
When I was developing my Zooming PDF viewer in a UIScrollView I found out that when running it on the Phone it actually already has the zooming implemented as part of the phone. But you could have a look at this, http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html it is a piece of sample code that tries to implement the functionality for zooming, this is want got me started.