Top places: solution of assignment 5 of CS193P (2013/2014)

Top places is a photos viewer based on Shutterbug that works on both iPhone and iPad. I think the only remarkable point is the solution of task 8. In particular I chose to manage photos like you find in Camera Roll. There are two functions that let you fulfill this goal. The first one

- (void)setMaxMinZoomScalesForCurrentBounds
{
    CGSize boundsSize = self.scrollView.bounds.size;
	
    // calculate min/max zoomscale
    CGFloat xScale = boundsSize.width  / self.imageView.image.size.width; // the scale needed to perfectly fit the image width-wise
    CGFloat yScale = boundsSize.height / self.imageView.image.size.height;// the scale needed to perfectly fit the image height-wise
    
    // take smaller scale
    CGFloat minScale = MIN(xScale, yScale);
    CGFloat maxScale = 1.0;
	
    // don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)
    if (minScale > maxScale) minScale = maxScale;
	
    self.scrollView.maximumZoomScale = maxScale;
    self.scrollView.minimumZoomScale = minScale;
    self.scrollView.zoomScale = minScale;
}

defines the max and min zoom scales while the second one

- (void)centerImageView
{
    // center the zoom view as it becomes smaller than the size of the screen
	CGSize boundsSize = self.scrollView.bounds.size;
	CGRect frameToCenter = self.imageView.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;
	
	self.imageView.frame = frameToCenter;
}

centers the image (therefore changes its frame) within the scrollview bounds. Before you run the project just remember to add your Flickr key

#define FlickrAPIKey @""

Download cs193p assignment 5 solution

Any question? Please, leave a comment below! 🙂

3 comments

  1. Hi,

    Thanks for the awesome solution. I have a question regarding the lazy instantiation. How come in this assignment (as well as in the shutterbug example from the cs193p lecture) there is no overriding of the getter methods of the public api, for example NSArray *photos.
    In previous lectures/assignments there has always been lazy instantiation of the getter methods eg.
    -(NSArray * )photos
    {
    if(!_photos) _photos = [NSArray alloc] init];
    }

    to ensure you aren’t sending a message to a nil pointer

    • Hi Dan!

      When you override the getter method of a property like this
      -(NSArray * )photos
      {
      if(!_photos) _photos = [NSArray alloc] init];
      return _photos;
      }
      you want to be sure that you always get an instance variable != nil (for instance you want to add objects to an array which has to be != nil otherwise they won’t be added). In FlickrPhotosTVC, I simply don’t need this checking because I set _photos from outside the class (within fetchPhotos:). Moreover, in Obj-C you can send messages to nil and nothing happens.
      To sum up:
      1) _photos != nil: the system reloads the tableView data (which causes cellForRowAtIndexPath, … to get called) and you see [self.photos count] cells.
      2) _photos = nil: there is one section without any rows (numberOfRowsInSection returns nil) and you see an empty table.

      Please, put a breakpoint to line 41 of FlickrPhotosTVC.m in order to see what I mean.
      Hope this helps!

Leave a Reply

Required fields are marked *.