Please note, this blog entry is from a previous course. You might want to check out the current one.
When the user then chooses a particular photo from the list, display it inside a UIScrollView that allows the user to pan and zoom.
Like in the previous task, you can safe some time be reusing code from Shutterbug.
In storyboard drag out a new view controller. Create a new subclass for it and link them. Add a scroll view and provide an outlet for it in the new class:
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
Create a push segue from the cell of the second table to the new view controller and set its identifier to “Show Image”:

Create a public property to hold the URL of the image:
@property (nonatomic, strong) NSURL *imageURL;
… and a private property to actually hold the image view and initialize it lazily:
@property (strong, nonatomic) UIImageView *imageView;
...
- (UIImageView *)imageView
{
if (!_imageView) {
_imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
}
return _imageView;
}
When ever somebody changes this URL, reset the image.
- (void)setImageURL:(NSURL *)imageURL
{
_imageURL = imageURL;
[self resetImage];
}
Finally the controller needs to be declared as delegate for the scroll view:
@interface ImageViewController () <UIScrollViewDelegate>
...
- (void)viewDidLoad
{
[super viewDidLoad];
[self.scrollView addSubview:self.imageView];
self.scrollView.minimumZoomScale = 0.2;
self.scrollView.maximumZoomScale = 5.0;
self.scrollView.delegate = self;
[self resetImage];
}
… and the table view controller needs to set the correct photo:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([sender isKindOfClass:[UITableViewCell class]]) {
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
if (indexPath) {
if ([segue.identifier isEqualToString:@"Show Image"]) {
if ([segue.destinationViewController respondsToSelector:@selector(setImageURL:)]) {
NSURL *url = [FlickrFetcher urlForPhoto:self.photos[indexPath.row]
format:FlickrPhotoFormatLarge];
[segue.destinationViewController performSelector:@selector(setImageURL:)
withObject:url];
[segue.destinationViewController setTitle:[self titleForRow:indexPath.row]];
}
}
}
}
}
Before you do so, check if there is a scroll view – which there is not when the view is not on screen yet, e.g. when preparing a segue … Resetting means removing an old image and its settings in the scroll view, loading it and setting the new properties:
- (void)resetImage
{
if (self.scrollView) {
self.scrollView.contentSize = CGSizeZero;
self.imageView.image = nil;
NSData *imageData = [[NSData alloc] initWithContentsOfURL:self.imageURL];
UIImage *image = [[UIImage alloc] initWithData:imageData];
if (image) {
self.scrollView.zoomScale = 1.0;
self.scrollView.contentSize = image.size;
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
}
}
}
The complete code is available on github.
Thanks for sharing! Just a note… As stated in lecture 9, I guess a delegate method to specify view to zoom is missing. I added the code below and the zoom worked fine:
– (UIView *)viewForZoomingInScrollView:(UIScrollView *)sender
{
return self.imageView;
}
Thanks again!