Added customisable photo caption capabilities.

Custom captions can be created by subclassing MWCaptionView (and MWPhoto to add more data per photo) and returning it to the proper delegate method.
This commit is contained in:
Michael Waterfall
2011-12-30 20:39:32 +01:00
parent 0b624f575a
commit a00fcced07
11 changed files with 200 additions and 22 deletions

33
Classes/MWCaptionView.h Normal file
View File

@@ -0,0 +1,33 @@
//
// MWCaptionView.h
// MWPhotoBrowser
//
// Created by Michael Waterfall on 30/12/2011.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
@class MWPhoto;
@interface MWCaptionView : UIView {
MWPhoto *_photo;
UILabel *_label;
}
// Init
- (id)initWithPhoto:(MWPhoto *)photo;
// To create your own custom caption view, subclass this view
// and override the following two methods:
// Override -setupCaption so setup your subviews and customise the appearance
// of your custom caption
- (void)setupCaption;
// Override -sizeThatFits: and return a CGSize specifying the height of your
// custom caption view. With width property is ignored and the caption is displayed
// the full width of the screen
- (CGSize)sizeThatFits:(CGSize)size;
@end

60
Classes/MWCaptionView.m Normal file
View File

@@ -0,0 +1,60 @@
//
// MWCaptionView.m
// MWPhotoBrowser
//
// Created by Michael Waterfall on 30/12/2011.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#import "MWCaptionView.h"
#import "MWPhoto.h"
static const CGFloat labelPadding = 10;
@implementation MWCaptionView
- (id)initWithPhoto:(MWPhoto *)photo {
self = [super initWithFrame:CGRectMake(0, 0, 320, 44)]; // Random initial frame
if (self) {
_photo = [photo retain];
self.opaque = NO;
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6];
self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
[self setupCaption];
}
return self;
}
- (CGSize)sizeThatFits:(CGSize)size {
CGFloat maxHeight = 9999;
if (_label.numberOfLines > 0) maxHeight = _label.font.leading*_label.numberOfLines;
CGSize textSize = [_label.text sizeWithFont:_label.font
constrainedToSize:CGSizeMake(size.width - labelPadding*2, maxHeight)
lineBreakMode:_label.lineBreakMode];
return CGSizeMake(size.width, textSize.height + labelPadding * 2);
}
- (void)setupCaption {
_label = [[UILabel alloc] initWithFrame:CGRectMake(labelPadding, 0,
self.bounds.size.width-labelPadding*2,
self.bounds.size.height)];
_label.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_label.opaque = NO;
_label.text = _photo.caption ? _photo.caption : @"[No Title]";
_label.backgroundColor = [UIColor clearColor];
_label.textAlignment = UITextAlignmentCenter;
_label.lineBreakMode = UILineBreakModeWordWrap;
_label.numberOfLines = 3;
_label.textColor = [UIColor whiteColor];
_label.shadowColor = [UIColor blackColor];
_label.shadowOffset = CGSizeMake(1, 1);
[self addSubview:_label];
}
- (void)dealloc {
[_label release];
[_photo release];
[super dealloc];
}
@end

View File

@@ -26,11 +26,17 @@
// Image // Image
UIImage *_underlyingImage; UIImage *_underlyingImage;
// Other
NSString *_caption;
// Delegate // Delegate
id <MWPhotoDelegate> _photoLoadingDelegate; id <MWPhotoDelegate> _photoLoadingDelegate;
} }
// Properties
@property (nonatomic, retain) NSString *caption;
// Class // Class
+ (MWPhoto *)photoWithImage:(UIImage *)image; + (MWPhoto *)photoWithImage:(UIImage *)image;
+ (MWPhoto *)photoWithFilePath:(NSString *)path; + (MWPhoto *)photoWithFilePath:(NSString *)path;

View File

@@ -21,7 +21,8 @@
// Properties // Properties
@synthesize underlyingImage = _underlyingImage, @synthesize underlyingImage = _underlyingImage,
photoLoadingDelegate = _photoLoadingDelegate; photoLoadingDelegate = _photoLoadingDelegate,
caption = _caption;
#pragma mark Class Methods #pragma mark Class Methods
@@ -61,6 +62,7 @@ photoLoadingDelegate = _photoLoadingDelegate;
} }
- (void)dealloc { - (void)dealloc {
[_caption release];
[[SDWebImageManager sharedManager] cancelForDelegate:self]; [[SDWebImageManager sharedManager] cancelForDelegate:self];
[_photoPath release]; [_photoPath release];
[_photoURL release]; [_photoURL release];

View File

@@ -8,6 +8,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "MWPhoto.h" #import "MWPhoto.h"
#import "MWCaptionView.h"
// Debug Logging // Debug Logging
#if 0 // Set to 1 to enable debug logging #if 0 // Set to 1 to enable debug logging
@@ -75,4 +76,5 @@
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser; - (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser;
- (MWPhoto *)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index; - (MWPhoto *)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index;
@optional @optional
- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index;
@end @end

View File

@@ -46,6 +46,7 @@
- (CGSize)contentSizeForPagingScrollView; - (CGSize)contentSizeForPagingScrollView;
- (CGPoint)contentOffsetForPageAtIndex:(NSUInteger)index; - (CGPoint)contentOffsetForPageAtIndex:(NSUInteger)index;
- (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation; - (CGRect)frameForToolbarAtOrientation:(UIInterfaceOrientation)orientation;
- (CGRect)frameForCaptionView:(MWCaptionView *)captionView atIndex:(NSUInteger)index;
// Navigation // Navigation
- (void)updateNavigation; - (void)updateNavigation;
@@ -58,6 +59,7 @@
- (void)hideControlsAfterDelay; - (void)hideControlsAfterDelay;
- (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated; - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated;
- (void)toggleControls; - (void)toggleControls;
- (BOOL)areControlsHidden;
// Data // Data
- (NSUInteger)numberOfPhotos; - (NSUInteger)numberOfPhotos;
@@ -342,7 +344,9 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
// Adjust frames and configuration of each visible page // Adjust frames and configuration of each visible page
for (MWZoomingScrollView *page in _visiblePages) { for (MWZoomingScrollView *page in _visiblePages) {
page.frame = [self frameForPageAtIndex:PAGE_INDEX(page)]; NSUInteger index = PAGE_INDEX(page);
page.frame = [self frameForPageAtIndex:index];
page.captionView.frame = [self frameForCaptionView:page.captionView atIndex:index];
[page setMaxMinZoomScalesForCurrentBounds]; [page setMaxMinZoomScalesForCurrentBounds];
} }
@@ -439,6 +443,18 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
return photo; return photo;
} }
- (MWCaptionView *)captionViewForPhotoAtIndex:(NSUInteger)index {
MWCaptionView *captionView = nil;
if ([_delegate respondsToSelector:@selector(photoBrowser:captionViewForPhotoAtIndex:)]) {
captionView = [_delegate photoBrowser:self captionViewForPhotoAtIndex:index];
} else {
MWPhoto *photo = [self photoAtIndex:index];
if (photo.caption) captionView = [[[MWCaptionView alloc] initWithPhoto:photo] autorelease];
}
captionView.alpha = [self areControlsHidden] ? 0 : 1; // Initial alpha
return captionView;
}
- (UIImage *)imageForPhoto:(MWPhoto *)photo { - (UIImage *)imageForPhoto:(MWPhoto *)photo {
if (photo) { if (photo) {
// Get image or obtain in background // Get image or obtain in background
@@ -521,18 +537,20 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
pageIndex = PAGE_INDEX(page); pageIndex = PAGE_INDEX(page);
if (pageIndex < (NSUInteger)iFirstIndex || pageIndex > (NSUInteger)iLastIndex) { if (pageIndex < (NSUInteger)iFirstIndex || pageIndex > (NSUInteger)iLastIndex) {
[_recycledPages addObject:page]; [_recycledPages addObject:page];
[page prepareForReuse]; // Cleanup [page prepareForReuse];
MWLog(@"Removed page at index %i", PAGE_INDEX(page));
[page removeFromSuperview]; [page removeFromSuperview];
MWLog(@"Removed page at index %i", PAGE_INDEX(page));
} }
} }
[_visiblePages minusSet:_recycledPages]; [_visiblePages minusSet:_recycledPages];
// Only keep 2 recycled pages while (_recycledPages.count > 2) // Only keep 2 recycled pages
while (_recycledPages.count > 2) [_recycledPages removeObject:[_recycledPages anyObject]]; [_recycledPages removeObject:[_recycledPages anyObject]];
// Add missing pages // Add missing pages
for (NSUInteger index = (NSUInteger)iFirstIndex; index <= (NSUInteger)iLastIndex; index++) { for (NSUInteger index = (NSUInteger)iFirstIndex; index <= (NSUInteger)iLastIndex; index++) {
if (![self isDisplayingPageForIndex:index]) { if (![self isDisplayingPageForIndex:index]) {
// Add new page
MWZoomingScrollView *page = [self dequeueRecycledPage]; MWZoomingScrollView *page = [self dequeueRecycledPage];
if (!page) { if (!page) {
page = [[[MWZoomingScrollView alloc] initWithPhotoBrowser:self] autorelease]; page = [[[MWZoomingScrollView alloc] initWithPhotoBrowser:self] autorelease];
@@ -540,7 +558,14 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
[self configurePage:page forIndex:index]; [self configurePage:page forIndex:index];
[_visiblePages addObject:page]; [_visiblePages addObject:page];
[_pagingScrollView addSubview:page]; [_pagingScrollView addSubview:page];
MWLog(@"Added page at index %i", PAGE_INDEX(page)); MWLog(@"Added page at index %i", index);
// Add caption
MWCaptionView *captionView = [self captionViewForPhotoAtIndex:index];
captionView.frame = [self frameForCaptionView:captionView atIndex:index];
[_pagingScrollView addSubview:captionView];
page.captionView = captionView;
} }
} }
@@ -668,6 +693,14 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
return CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height); return CGRectMake(0, self.view.bounds.size.height - height, self.view.bounds.size.width, height);
} }
- (CGRect)frameForCaptionView:(MWCaptionView *)captionView atIndex:(NSUInteger)index {
CGRect pageFrame = [self frameForPageAtIndex:index];
captionView.frame = CGRectMake(0, 0, pageFrame.size.width, 44); // set initial frame
CGSize captionSize = [captionView sizeThatFits:CGSizeMake(pageFrame.size.width, 0)];
CGRect captionFrame = CGRectMake(pageFrame.origin.x, pageFrame.size.height - captionSize.height - (_toolbar.superview?_toolbar.frame.size.height:0), pageFrame.size.width, captionSize.height);
return captionFrame;
}
#pragma mark - UIScrollView Delegate #pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
@@ -766,14 +799,22 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
CGRect navBarFrame = self.navigationController.navigationBar.frame; CGRect navBarFrame = self.navigationController.navigationBar.frame;
navBarFrame.origin.y = statusBarHeight; navBarFrame.origin.y = statusBarHeight;
self.navigationController.navigationBar.frame = navBarFrame; self.navigationController.navigationBar.frame = navBarFrame;
// Captions
NSMutableSet *captionViews = [[[NSMutableSet alloc] initWithCapacity:_visiblePages.count] autorelease];
for (MWZoomingScrollView *page in _visiblePages) {
if (page.captionView) [captionViews addObject:page.captionView];
}
// Bars // Animate
if (animated) { if (animated) {
[UIView beginAnimations:nil context:nil]; [UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.35]; [UIView setAnimationDuration:0.35];
} }
[self.navigationController.navigationBar setAlpha:hidden ? 0 : 1]; CGFloat alpha = hidden ? 0 : 1;
[_toolbar setAlpha:hidden ? 0 : 1]; [self.navigationController.navigationBar setAlpha:alpha];
[_toolbar setAlpha:alpha];
for (UIView *v in captionViews) v.alpha = alpha;
if (animated) [UIView commitAnimations]; if (animated) [UIView commitAnimations];
// Control hiding timer // Control hiding timer
@@ -794,14 +835,15 @@ navigationBarBackgroundImageLandscapePhone = _navigationBarBackgroundImageLandsc
// Enable/disable control visiblity timer // Enable/disable control visiblity timer
- (void)hideControlsAfterDelay { - (void)hideControlsAfterDelay {
if (!_disappearing && ![UIApplication sharedApplication].isStatusBarHidden) { if (!_disappearing && ![self areControlsHidden]) {
[self cancelControlHiding]; [self cancelControlHiding];
_controlVisibilityTimer = [[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(hideControls) userInfo:nil repeats:NO] retain]; _controlVisibilityTimer = [[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(hideControls) userInfo:nil repeats:NO] retain];
} }
} }
- (BOOL)areControlsHidden { return [UIApplication sharedApplication].isStatusBarHidden; }
- (void)hideControls { [self setControlsHidden:YES animated:YES]; } - (void)hideControls { [self setControlsHidden:YES animated:YES]; }
- (void)toggleControls { [self setControlsHidden:![UIApplication sharedApplication].isStatusBarHidden animated:YES]; } - (void)toggleControls { [self setControlsHidden:![self areControlsHidden] animated:YES]; }
#pragma mark - Properties #pragma mark - Properties

View File

@@ -10,19 +10,24 @@
#import "UIImageViewTap.h" #import "UIImageViewTap.h"
#import "UIViewTap.h" #import "UIViewTap.h"
@class MWPhotoBrowser, MWPhoto; @class MWPhotoBrowser, MWPhoto, MWCaptionView;
@interface MWZoomingScrollView : UIScrollView <UIScrollViewDelegate, UIImageViewTapDelegate, UIViewTapDelegate> { @interface MWZoomingScrollView : UIScrollView <UIScrollViewDelegate, UIImageViewTapDelegate, UIViewTapDelegate> {
MWPhotoBrowser *_photoBrowser; MWPhotoBrowser *_photoBrowser;
MWPhoto *_photo; MWPhoto *_photo;
// This view references the related caption view for simplified
// handling in photo browser
MWCaptionView *_captionView;
UIViewTap *_tapView; // for background taps UIViewTap *_tapView; // for background taps
UIImageViewTap *_photoImageView; UIImageViewTap *_photoImageView;
UIActivityIndicatorView *_spinner; UIActivityIndicatorView *_spinner;
} }
@property (nonatomic, retain) MWCaptionView *captionView;
@property (nonatomic, retain) MWPhoto *photo; @property (nonatomic, retain) MWPhoto *photo;
- (id)initWithPhotoBrowser:(MWPhotoBrowser *)browser; - (id)initWithPhotoBrowser:(MWPhotoBrowser *)browser;

View File

@@ -26,7 +26,7 @@
@implementation MWZoomingScrollView @implementation MWZoomingScrollView
@synthesize photoBrowser = _photoBrowser, photo = _photo; @synthesize photoBrowser = _photoBrowser, photo = _photo, captionView = _captionView;
- (id)initWithPhotoBrowser:(MWPhotoBrowser *)browser { - (id)initWithPhotoBrowser:(MWPhotoBrowser *)browser {
if ((self = [super init])) { if ((self = [super init])) {
@@ -87,6 +87,8 @@
- (void)prepareForReuse { - (void)prepareForReuse {
[_photo releasePhoto]; [_photo releasePhoto];
self.photo = nil; self.photo = nil;
[_captionView removeFromSuperview];
self.captionView = nil;
} }
#pragma mark - Image #pragma mark - Image

View File

@@ -87,16 +87,28 @@
// Browser // Browser
NSMutableArray *photos = [[NSMutableArray alloc] init]; NSMutableArray *photos = [[NSMutableArray alloc] init];
MWPhoto *photo;
switch (indexPath.row) { switch (indexPath.row) {
case 0: case 0:
[photos addObject:[MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo2l" ofType:@"jpg"]]]; photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo2l" ofType:@"jpg"]];
photo.caption = @"The London Eye is a giant Ferris wheel situated on the banks of the River Thames, in London, England.";
[photos addObject:photo];
break; break;
case 1: case 1: {
[photos addObject:[MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo1l" ofType:@"jpg"]]]; photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo1l" ofType:@"jpg"]];
[photos addObject:[MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo2l" ofType:@"jpg"]]]; photo.caption = @"Grotto of the Madonna";
[photos addObject:[MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo3l" ofType:@"jpg"]]]; [photos addObject:photo];
[photos addObject:[MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo4l" ofType:@"jpg"]]]; photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo2l" ofType:@"jpg"]];
photo.caption = @"The London Eye is a giant Ferris wheel situated on the banks of the River Thames, in London, England.";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo3l" ofType:@"jpg"]];
photo.caption = @"York Floods";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:@"photo4l" ofType:@"jpg"]];
photo.caption = @"Campervan";
[photos addObject:photo];
break; break;
}
case 2: case 2:
[photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3567/3523321514_371d9ac42f.jpg"]]]; [photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3567/3523321514_371d9ac42f.jpg"]]];
[photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3629/3339128908_7aecabc34b.jpg"]]]; [photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3629/3339128908_7aecabc34b.jpg"]]];
@@ -146,5 +158,12 @@
return nil; return nil;
} }
//- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index {
// MWCaptionView *captionView = nil;
// MWPhoto *photo = [_photos objectAtIndex:index];
// captionView = [[[MWCaptionView alloc] initWithPhoto:photo] autorelease];
// return captionView;
//}
@end @end

View File

@@ -21,6 +21,7 @@
4C15BF4914ACDD64004F9CA6 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4014ACDD64004F9CA6 /* SDWebImagePrefetcher.m */; }; 4C15BF4914ACDD64004F9CA6 /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4014ACDD64004F9CA6 /* SDWebImagePrefetcher.m */; };
4C15BF4A14ACDD64004F9CA6 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4214ACDD64004F9CA6 /* UIButton+WebCache.m */; }; 4C15BF4A14ACDD64004F9CA6 /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4214ACDD64004F9CA6 /* UIButton+WebCache.m */; };
4C15BF4B14ACDD64004F9CA6 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4414ACDD64004F9CA6 /* UIImageView+WebCache.m */; }; 4C15BF4B14ACDD64004F9CA6 /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF4414ACDD64004F9CA6 /* UIImageView+WebCache.m */; };
4C15BF5214AE300F004F9CA6 /* MWCaptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C15BF5114AE300F004F9CA6 /* MWCaptionView.m */; };
4C4156C61277301E00C96767 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C4156C51277301E00C96767 /* MainWindow-iPad.xib */; }; 4C4156C61277301E00C96767 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C4156C51277301E00C96767 /* MainWindow-iPad.xib */; };
4C48EFD2126F90B100F85546 /* UIViewTap.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C48EFD1126F90B100F85546 /* UIViewTap.m */; }; 4C48EFD2126F90B100F85546 /* UIViewTap.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C48EFD1126F90B100F85546 /* UIViewTap.m */; };
4C667B2D1270AFCE0008B630 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C667B2C1270AFCE0008B630 /* Menu.m */; }; 4C667B2D1270AFCE0008B630 /* Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C667B2C1270AFCE0008B630 /* Menu.m */; };
@@ -71,6 +72,8 @@
4C15BF4214ACDD64004F9CA6 /* UIButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIButton+WebCache.m"; path = "SDWebImage/UIButton+WebCache.m"; sourceTree = SOURCE_ROOT; }; 4C15BF4214ACDD64004F9CA6 /* UIButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIButton+WebCache.m"; path = "SDWebImage/UIButton+WebCache.m"; sourceTree = SOURCE_ROOT; };
4C15BF4314ACDD64004F9CA6 /* UIImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImageView+WebCache.h"; path = "SDWebImage/UIImageView+WebCache.h"; sourceTree = SOURCE_ROOT; }; 4C15BF4314ACDD64004F9CA6 /* UIImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImageView+WebCache.h"; path = "SDWebImage/UIImageView+WebCache.h"; sourceTree = SOURCE_ROOT; };
4C15BF4414ACDD64004F9CA6 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+WebCache.m"; path = "SDWebImage/UIImageView+WebCache.m"; sourceTree = SOURCE_ROOT; }; 4C15BF4414ACDD64004F9CA6 /* UIImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+WebCache.m"; path = "SDWebImage/UIImageView+WebCache.m"; sourceTree = SOURCE_ROOT; };
4C15BF5014AE300F004F9CA6 /* MWCaptionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWCaptionView.h; sourceTree = "<group>"; };
4C15BF5114AE300F004F9CA6 /* MWCaptionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWCaptionView.m; sourceTree = "<group>"; };
4C4156C51277301E00C96767 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; }; 4C4156C51277301E00C96767 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "Resources-iPad/MainWindow-iPad.xib"; sourceTree = "<group>"; };
4C48EFD0126F90B100F85546 /* UIViewTap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIViewTap.h; sourceTree = "<group>"; }; 4C48EFD0126F90B100F85546 /* UIViewTap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIViewTap.h; sourceTree = "<group>"; };
4C48EFD1126F90B100F85546 /* UIViewTap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIViewTap.m; sourceTree = "<group>"; }; 4C48EFD1126F90B100F85546 /* UIViewTap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIViewTap.m; sourceTree = "<group>"; };
@@ -237,6 +240,8 @@
4C75D46E126B659A004D0ECF /* MWPhoto.m */, 4C75D46E126B659A004D0ECF /* MWPhoto.m */,
4CC82BE41266804500C05633 /* MWZoomingScrollView.h */, 4CC82BE41266804500C05633 /* MWZoomingScrollView.h */,
4CC82BE51266804500C05633 /* MWZoomingScrollView.m */, 4CC82BE51266804500C05633 /* MWZoomingScrollView.m */,
4C15BF5014AE300F004F9CA6 /* MWCaptionView.h */,
4C15BF5114AE300F004F9CA6 /* MWCaptionView.m */,
); );
name = MWPhotoBrowser; name = MWPhotoBrowser;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -343,6 +348,7 @@
4C15BF4914ACDD64004F9CA6 /* SDWebImagePrefetcher.m in Sources */, 4C15BF4914ACDD64004F9CA6 /* SDWebImagePrefetcher.m in Sources */,
4C15BF4A14ACDD64004F9CA6 /* UIButton+WebCache.m in Sources */, 4C15BF4A14ACDD64004F9CA6 /* UIButton+WebCache.m in Sources */,
4C15BF4B14ACDD64004F9CA6 /* UIImageView+WebCache.m in Sources */, 4C15BF4B14ACDD64004F9CA6 /* UIImageView+WebCache.m in Sources */,
4C15BF5214AE300F004F9CA6 /* MWCaptionView.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -39,10 +39,11 @@ If desired, you can choose which photo is displayed first:
## Outstanding issues and improvements ## Outstanding issues and improvements
- Photo captions. - Action button
- Modify README to describe new features.
- Test with larger images 3-4MB and check performance.
- Check memory usage and for leaks. - Check memory usage and for leaks.
- Create static library which can be added to projects easier. - Create static library which can be added to projects easier.
- Test with larger images 3-4MB and check performance.
## Licence ## Licence