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!