Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit 3175d4bcb5e6e1839342894257e8e16082f382ae 0 parents
@cxa cxa authored
Showing with 4,141 additions and 0 deletions.
  1. BIN  0.jpg
  2. BIN  1.jpg
  3. BIN  10.jpg
  4. BIN  11.jpg
  5. BIN  12.jpg
  6. BIN  13.jpg
  7. BIN  14.jpg
  8. BIN  15.jpg
  9. BIN  16.jpg
  10. BIN  17.jpg
  11. BIN  18.jpg
  12. BIN  19.jpg
  13. BIN  2.jpg
  14. BIN  20.jpg
  15. BIN  21.jpg
  16. BIN  22.jpg
  17. BIN  3.jpg
  18. BIN  4.jpg
  19. BIN  5.jpg
  20. BIN  6.jpg
  21. BIN  7.jpg
  22. BIN  8.jpg
  23. BIN  9.jpg
  24. BIN  Classes/.DS_Store
  25. +20 −0 Classes/XANAppDelegate.h
  26. +94 −0 Classes/XANAppDelegate.m
  27. +22 −0 Classes/XANImageScrollView.h
  28. +103 −0 Classes/XANImageScrollView.m
  29. +28 −0 Classes/XANImageViewController.h
  30. +295 −0 Classes/XANImageViewController.m
  31. +34 −0 Classes/XANThumbsCell.h
  32. +106 −0 Classes/XANThumbsCell.m
  33. +22 −0 Classes/XANThumbsViewController.h
  34. +228 −0 Classes/XANThumbsViewController.m
  35. +9 −0 LICENSE
  36. +422 −0 MainWindow.xib
  37. +13 −0 README.textile
  38. +32 −0 XAN-Info.plist
  39. +385 −0 XANImageBrowser.xcodeproj/project.pbxproj
  40. +1,443 −0 XANImageBrowser.xcodeproj/xan.mode1v3
  41. +854 −0 XANImageBrowser.xcodeproj/xan.pbxuser
  42. +14 −0 XAN_Prefix.pch
  43. BIN  arrow_left.png
  44. BIN  arrow_left@2x.png
  45. BIN  arrow_right.png
  46. BIN  arrow_right@2x.png
  47. +17 −0 main.m
BIN  0.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  10.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  11.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  12.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  13.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  14.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  15.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  16.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  17.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  18.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  19.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  2.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  20.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  21.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  22.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  3.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  4.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  5.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  6.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  7.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  8.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  9.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  Classes/.DS_Store
Binary file not shown
20 Classes/XANAppDelegate.h
@@ -0,0 +1,20 @@
+//
+// XANAppDelegate.h
+// XAN
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "XANThumbsViewController.h"
+
+@interface XANAppDelegate : NSObject <UIApplicationDelegate> {
+ UIWindow *window;
+ UINavigationController *navigationController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+
+@end
+
94 Classes/XANAppDelegate.m
@@ -0,0 +1,94 @@
+//
+// XANAppDelegate.m
+// XAN
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import "XANAppDelegate.h"
+#import "XANThumbsViewController.h"
+
+@implementation XANAppDelegate
+
+@synthesize window;
+
+#pragma mark -
+#pragma mark Application lifecycle
+
+- (BOOL)application:(UIApplication *)application
+didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ application.statusBarStyle = UIStatusBarStyleBlackTranslucent;
+
+ NSArray *imagePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"jpg" inDirectory:@""];
+ XANThumbsViewController *tvc = [[XANThumbsViewController alloc] initWithimagePaths:imagePaths];
+ navigationController = [[UINavigationController alloc] initWithRootViewController:tvc];
+ [tvc release];
+
+ [self.window addSubview:navigationController.view];
+ [self.window makeKeyAndVisible];
+
+ return YES;
+}
+
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+ /*
+ Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+ */
+}
+
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ /*
+ Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
+ */
+}
+
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ /*
+ Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
+ */
+}
+
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ /*
+ Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ */
+}
+
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ /*
+ Called when the application is about to terminate.
+ See also applicationDidEnterBackground:.
+ */
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
+ /*
+ Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
+ */
+}
+
+
+- (void)dealloc
+{
+ [window release];
+ [navigationController release];
+
+ [super dealloc];
+}
+
+@end
+
22 Classes/XANImageScrollView.h
@@ -0,0 +1,22 @@
+//
+// XANImageScrollView.h
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/18/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@interface XANImageScrollView : UIScrollView <UIScrollViewDelegate> {
+ UIImageView *imageView;
+ UIImage *image;
+ NSUInteger index;
+}
+
+@property (nonatomic, retain, readonly) UIImageView *imageView;
+@property (nonatomic, retain) UIImage *image;
+@property (nonatomic) NSUInteger index;
+
+@end
103 Classes/XANImageScrollView.m
@@ -0,0 +1,103 @@
+//
+// XANImageScrollView.m
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/18/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import "XANImageScrollView.h"
+
+@implementation XANImageScrollView
+@synthesize imageView, image;
+@synthesize index;
+
+- (void)setImage:(UIImage *)theImage
+{
+ [theImage retain];
+ [image release];
+ image = theImage;
+
+ if (image == nil){
+ imageView.image = nil;
+ return;
+ }
+
+ self.zoomScale = 1.0;
+
+ CGSize imageSize = image.size;
+ CGSize finalSize = self.bounds.size;
+ if (imageSize.width > imageSize.height){
+ finalSize.height = imageSize.height * (finalSize.width/imageSize.width);
+ if (finalSize.height > self.frame.size.height){
+ finalSize.width *= (self.frame.size.height/finalSize.height);
+ finalSize.height = self.frame.size.height;
+ }
+ } else {
+ finalSize.width = imageSize.width * (finalSize.height/imageSize.height);
+ if (finalSize.width > self.frame.size.width){
+ finalSize.height *= (self.frame.size.width/finalSize.width);
+ finalSize.width = self.frame.size.width;
+ }
+ }
+
+ imageView.image = image;
+ imageView.frame = CGRectMake(0, 0, finalSize.width, finalSize.height);
+
+ CGFloat maximumZoomScale = imageSize.height / finalSize.height;
+ CGFloat minimumZoomScale = 1.0;
+ if (maximumZoomScale < 1.5) maximumZoomScale = 1.5;
+ if (imageSize.height < self.bounds.size.height && imageSize.width < self.bounds.size.width) minimumZoomScale = finalSize.width / imageSize.width;
+
+ self.maximumZoomScale = maximumZoomScale;
+ self.minimumZoomScale = minimumZoomScale;
+
+ [self setNeedsLayout];
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if (self = [super initWithFrame:frame]){
+ imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
+ imageView.autoresizesSubviews = NO;
+ imageView.contentMode = UIViewContentModeScaleToFill;
+ [self addSubview:imageView];
+ [imageView release];
+ self.backgroundColor = [UIColor blackColor];
+ self.delegate = self;
+ }
+
+ return self;
+}
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+ CGSize boundsSize = self.bounds.size;
+ CGRect frameToCenter = imageView.frame;
+
+ if (frameToCenter.size.width < boundsSize.width)
+ frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
+ else
+ frameToCenter.origin.x = 0;
+
+ if (frameToCenter.size.height < boundsSize.height)
+ frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
+ else
+ frameToCenter.origin.y = 0;
+
+ imageView.frame = frameToCenter;
+}
+
+- (void)dealloc
+{
+ [super dealloc];
+}
+
+#pragma mark UIScrollViewDelegate
+- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
+{
+ return imageView;
+}
+
+@end
28 Classes/XANImageViewController.h
@@ -0,0 +1,28 @@
+//
+// XANImageViewController.h
+// XANImageBrowser
+//
+// Created by Chen Xian'an on 12/18/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface XANImageViewController : UIViewController<UIScrollViewDelegate> {
+ NSArray *imagePaths;
+ NSUInteger currentImageIndex;
+ UIImage *selectedImage;
+ UIScrollView *pagingScrollView;
+
+ NSMutableSet *visiblePages;
+ NSMutableSet *recycledPages;
+
+ UIInterfaceOrientation fromInterfaceOrientation;
+
+ UIBarButtonItem *prevItem;
+ UIBarButtonItem *nextItem;
+}
+
+- (id)initWithImagePaths:(NSArray *)imagePaths initialImageIndex:(NSUInteger)initialImageIndex;
+
+@end
295 Classes/XANImageViewController.m
@@ -0,0 +1,295 @@
+//
+// XANImageViewController.m
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/18/PAGE_GAP/2.
+// Copyright 20PAGE_GAP/2 lazyapps.com. All rights reserved.
+//
+
+#import "XANImageViewController.h"
+#import "XANImageScrollView.h"
+
+#define PAGE_GAP 20.0
+
+@interface XANImageViewController()
+- (void)updatePagingScrollViewLayout;
+- (void)updatePagingScrollViewBounds;
+- (void)updatePage:(XANImageScrollView *)page forIndex:(NSUInteger)index;
+- (BOOL)isDisplayingPageForIndex:(NSUInteger)index;
+- (void)tilePages;
+- (XANImageScrollView *)dequeueRecycledPage;
+- (CGRect)pageBounds;
+@end
+
+@implementation XANImageViewController
+
+- (id)initWithImagePaths:(NSArray *)theImagePaths
+ initialImageIndex:(NSUInteger)theInitialImageIndex
+{
+ if (self = [super initWithNibName:nil bundle:nil]){
+ imagePaths = [theImagePaths retain];
+ currentImageIndex = theInitialImageIndex;
+ self.wantsFullScreenLayout = YES;
+
+ visiblePages = [[NSMutableSet alloc] initWithCapacity:0];
+ recycledPages = [[NSMutableSet alloc] initWithCapacity:0];
+ }
+
+ return self;
+}
+
+// Implement loadView to create a view hierarchy programmatically, without using a nib.
+- (void)loadView
+{
+ pagingScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
+ pagingScrollView.scrollIndicatorInsets = UIEdgeInsetsZero;
+ pagingScrollView.contentInset = UIEdgeInsetsZero;
+ pagingScrollView.alwaysBounceVertical = NO;
+ pagingScrollView.autoresizesSubviews = YES;
+ pagingScrollView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ pagingScrollView.pagingEnabled = YES;
+ pagingScrollView.delegate = self;
+ pagingScrollView.showsHorizontalScrollIndicator = NO;
+ pagingScrollView.showsVerticalScrollIndicator = NO;
+ pagingScrollView.backgroundColor = [UIColor blackColor];
+ [self updatePagingScrollViewLayout];
+ [self tilePages];
+
+ UIView *view = [[UIView alloc] initWithFrame:[self pageBounds]];
+ [view addSubview:pagingScrollView];
+ [pagingScrollView release];
+ self.view = view;
+ [view release];
+
+ prevItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"arrow_left"] style:UIBarButtonItemStylePlain target:self action:@selector(prevImage:)];
+ nextItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"arrow_right"] style:UIBarButtonItemStylePlain target:self action:@selector(nextImage:)];
+ prevItem.enabled = currentImageIndex > 0;
+ nextItem.enabled = currentImageIndex < [imagePaths count] - 1;
+ UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
+ NSArray *items = [[NSArray alloc] initWithObjects:flexibleItem, prevItem, flexibleItem, nextItem, flexibleItem, nil];
+ [prevItem release];
+ [nextItem release];
+ [flexibleItem release];
+
+ self.toolbarItems = items;
+ [items release];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+ self.navigationController.toolbarHidden = NO;
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+}
+
+- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+ duration:(NSTimeInterval)duration
+{
+ fromInterfaceOrientation = self.interfaceOrientation;
+}
+
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+ duration:(NSTimeInterval)duration
+{
+ if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) == UIInterfaceOrientationIsLandscape(fromInterfaceOrientation)) return;
+
+ [self updatePagingScrollViewLayout];
+ [self tilePages];
+ for (XANImageScrollView *page in visiblePages){
+ [self updatePage:page forIndex:page.index];
+ }
+}
+
+- (void)didReceiveMemoryWarning
+{
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+
+ // Release any cached data, images, etc. that aren't in use.
+}
+
+- (void)viewDidUnload
+{
+ [super viewDidUnload];
+ // Release any retained subviews of the main view.
+ // e.g. self.myOutlet = nil;
+}
+
+
+- (void)dealloc
+{
+ [imagePaths release];
+ [visiblePages release];
+ [recycledPages release];
+
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark UIScrollViewDelegate
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView
+{
+ [self tilePages];
+}
+
+- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
+{
+ CGRect visibleBounds = pagingScrollView.bounds;
+ currentImageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
+ currentImageIndex = MAX(currentImageIndex, 0);
+}
+
+#pragma mark privates
+- (void)updatePagingScrollViewLayout
+{
+ CGRect frame = [self pageBounds];
+ frame.origin.x -= PAGE_GAP/2;
+ frame.size.width += PAGE_GAP;
+ pagingScrollView.frame = frame;
+ pagingScrollView.contentSize = CGSizeMake(frame.size.width * [imagePaths count], frame.size.height);
+ [self updatePagingScrollViewBounds];
+}
+
+- (void)updatePagingScrollViewBounds
+{
+ CGRect bounds = pagingScrollView.bounds;
+ bounds.origin.x = pagingScrollView.frame.size.width * currentImageIndex;
+ pagingScrollView.bounds = bounds;
+}
+
+- (void)updatePage:(XANImageScrollView *)page
+ forIndex:(NSUInteger)index
+{
+ page.index = index;
+ CGRect frame = [self pageBounds];
+ frame.origin.x = (frame.size.width + PAGE_GAP) * page.index + PAGE_GAP/2;
+ page.frame = frame;
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagePaths objectAtIndex:index]];
+ page.image = image;
+ [image release];
+}
+
+- (BOOL)isDisplayingPageForIndex:(NSUInteger)index
+{
+ for (XANImageScrollView *page in visiblePages){
+ if (page.index == index)
+ return YES;
+ }
+
+ return NO;
+}
+
+- (void)tilePages
+{
+ CGRect visibleBounds = pagingScrollView.bounds;
+ NSUInteger firstNeededPageIndex = floorf(CGRectGetMinX(visibleBounds) / CGRectGetWidth(visibleBounds));
+ NSUInteger lastNeededPageIndex = floorf(CGRectGetMaxX(visibleBounds) / CGRectGetWidth(visibleBounds));
+ firstNeededPageIndex = MAX(firstNeededPageIndex, 0);
+ lastNeededPageIndex = MIN(lastNeededPageIndex, [imagePaths count]-1);
+
+ for (XANImageScrollView *page in visiblePages){
+ if (page.index < firstNeededPageIndex || page.index > lastNeededPageIndex){
+ [recycledPages addObject:page];
+ [page removeFromSuperview];
+ page.image = nil;
+ }
+ }
+
+ [visiblePages minusSet:recycledPages];
+
+ for (NSUInteger index=firstNeededPageIndex; index<=lastNeededPageIndex; index++){
+ if (![self isDisplayingPageForIndex:index]){
+ XANImageScrollView *page = [self dequeueRecycledPage];
+ if (page == nil){
+ page = [[[XANImageScrollView alloc] initWithFrame:CGRectZero] autorelease];
+ UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
+ singleTap.numberOfTapsRequired = 1;
+ UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
+ doubleTap.numberOfTapsRequired = 2;
+ [singleTap requireGestureRecognizerToFail:doubleTap];
+ [page addGestureRecognizer:singleTap];
+ [page addGestureRecognizer:doubleTap];
+ [singleTap release];
+ [doubleTap release];
+ }
+ [visiblePages addObject:page];
+ [pagingScrollView addSubview:page];
+ [self updatePage:page forIndex:index];
+ }
+ }
+}
+
+- (XANImageScrollView *)dequeueRecycledPage
+{
+ XANImageScrollView *page = [recycledPages anyObject];
+ if (page){
+ [[page retain] autorelease];
+ [recycledPages removeObject:page];
+ }
+
+ return page;
+}
+
+- (CGRect)pageBounds
+{
+ CGRect bounds = [UIScreen mainScreen].bounds;
+ if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){
+ CGFloat width = bounds.size.width;
+ bounds.size.width = bounds.size.height;
+ bounds.size.height = width;
+ }
+
+ return bounds;
+}
+
+#pragma mark UITapGestureRecognizer actions
+- (void)handleSingleTap:(UITapGestureRecognizer *)tgr
+{
+ BOOL hidden = [UIApplication sharedApplication].statusBarHidden;
+ [[UIApplication sharedApplication] setStatusBarHidden:!hidden withAnimation:UIStatusBarAnimationFade];
+ [self.navigationController setNavigationBarHidden:!hidden animated:YES];
+ [self.navigationController setToolbarHidden:!hidden animated:YES];
+}
+
+- (void)handleDoubleTap:(UITapGestureRecognizer *)tgr
+{
+ XANImageScrollView *page = (XANImageScrollView *)tgr.view;
+ float scale = page.zoomScale > page.minimumZoomScale ? page.minimumZoomScale : page.maximumZoomScale;
+ CGPoint center = [tgr locationInView:page];
+ CGRect zoomRect;
+ zoomRect.size.height = [page bounds].size.height / scale;
+ zoomRect.size.width = [page bounds].size.width / scale;
+ zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
+ zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
+
+ [page zoomToRect:zoomRect animated:YES];
+}
+
+#pragma mark UIBarButtonItem actions
+- (void)prevImage:(UIBarButtonItem *)sender
+{
+ currentImageIndex--;
+ if (currentImageIndex == 0) prevItem.enabled = NO;
+ if ([imagePaths count] > 1) nextItem.enabled = YES;
+
+ [self updatePagingScrollViewBounds];
+ [self tilePages];
+}
+
+- (void)nextImage:(UIBarButtonItem *)sender
+{
+ currentImageIndex++;
+ if (currentImageIndex == [imagePaths count] - 1) nextItem.enabled = NO;
+ if ([imagePaths count] > 1) prevItem.enabled = YES;
+
+ [self updatePagingScrollViewBounds];
+ [self tilePages];
+}
+
+@end
34 Classes/XANThumbsCell.h
@@ -0,0 +1,34 @@
+//
+// XANThumbCell.h
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#define kImageSize (CGSizeMake(75.0, 75.0))
+#define kSpacing 4.0
+#define kCapacityOfImagesInARowPortrait 4
+#define kCapacityOfImagesInARowLandscape 6
+
+@protocol XANThumbsCellDelegate
+- (void)didSelectPhotoAtIndex:(NSUInteger)index inRow:(NSUInteger)rowIndex;
+@end
+
+@interface XANThumbsCell : UITableViewCell {
+ NSUInteger numberOfImages;
+ NSUInteger capacityOfImages;
+ NSUInteger rowIndex;
+ __weak NSObject <XANThumbsCellDelegate> *thumbDelegate;
+}
+
+@property (nonatomic) NSUInteger numberOfImages;
+@property (nonatomic) NSUInteger capacityOfImages;
+@property (nonatomic) NSUInteger rowIndex;
+
+- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier thumbDelegate:(NSObject <XANThumbsCellDelegate> *)thumbDelegate;
+- (void)updateImage:(UIImage *)image forColumn:(NSUInteger)column;
+
+@end
106 Classes/XANThumbsCell.m
@@ -0,0 +1,106 @@
+//
+// XANThumbCell.m
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import "XANThumbsCell.h"
+#import <QuartzCore/QuartzCore.h>
+
+#define TAG_BASE 1000
+
+@interface XANThumbsCell()
+- (CGFloat)firstImageLeftOffset;
+- (UIButton *)createButtonForColumn:(NSUInteger)column;
+@end
+
+@implementation XANThumbsCell
+@synthesize numberOfImages, capacityOfImages, rowIndex;
+
+- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
+ thumbDelegate:(NSObject <XANThumbsCellDelegate> *)theThumbDelegate
+
+{
+ if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]){
+ self.selectionStyle = UITableViewCellSelectionStyleNone;
+ thumbDelegate = theThumbDelegate;
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ thumbDelegate = nil;
+
+ [super dealloc];
+}
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+
+ CGRect r = self.contentView.frame;
+ r.size.width = self.bounds.size.width;
+ self.contentView.frame = r;
+
+ NSUInteger numberOfButtons = [self.contentView.subviews count];
+ if (numberOfButtons == 0) numberOfButtons = numberOfImages;
+
+ for (NSUInteger i=0; i<numberOfButtons; i++){
+ UIButton *button = (UIButton *)[self.contentView viewWithTag:TAG_BASE+i];
+ if (i < numberOfImages){
+ if (!button) [self createButtonForColumn:i];
+ else {
+ CGFloat x = [self firstImageLeftOffset] + (kImageSize.width + kSpacing)*i;
+ button.frame = CGRectMake(x, 0, kImageSize.width, kImageSize.height);
+ }
+ } else {
+ [button removeFromSuperview];
+ }
+ }
+}
+
+#pragma mark methods
+- (void)updateImage:(UIImage *)image
+ forColumn:(NSUInteger)column
+{
+ UIButton *button = (UIButton *)[self.contentView viewWithTag:TAG_BASE+column];
+ if (!button){
+ button = [self createButtonForColumn:column];
+ }
+
+ [button setImage:image forState:UIControlStateNormal];
+}
+
+#pragma mark button action
+- (void)didTouchButton:(UIButton *)button
+{
+ if (thumbDelegate && [thumbDelegate respondsToSelector:@selector(didSelectPhotoAtIndex:inRow:)]){
+ [thumbDelegate didSelectPhotoAtIndex:(button.tag-TAG_BASE) inRow:rowIndex];
+ }
+}
+
+#pragma mark privates
+- (CGFloat)firstImageLeftOffset
+{
+ return (self.bounds.size.width - kImageSize.width * capacityOfImages - kSpacing * (capacityOfImages-1)) / 2;
+}
+
+- (UIButton *)createButtonForColumn:(NSUInteger)column
+{
+ UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
+ button.tag = TAG_BASE + column;
+ button.layer.borderWidth = 1.0;
+ button.layer.borderColor = [UIColor darkGrayColor].CGColor;
+ [button addTarget:self action:@selector(didTouchButton:) forControlEvents:UIControlEventTouchUpInside];
+ CGFloat x = [self firstImageLeftOffset] + (kImageSize.width + kSpacing) * column;
+ button.frame = CGRectMake(x, 0, kImageSize.width, kImageSize.height);
+ [self.contentView addSubview:button];
+
+ return button;
+}
+
+@end
22 Classes/XANThumbsViewController.h
@@ -0,0 +1,22 @@
+//
+// XANThumbsViewController.h
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "XANThumbsCell.h"
+
+@interface XANThumbsViewController : UITableViewController <XANThumbsCellDelegate>{
+ NSArray *imagePaths;
+@private
+ NSMutableArray *thumbImages;
+}
+
+@property (nonatomic, retain) NSArray *imagePaths;
+
+- (id)initWithimagePaths:(NSArray *)imagePaths;
+
+@end
228 Classes/XANThumbsViewController.m
@@ -0,0 +1,228 @@
+//
+// XANThumbsViewController.m
+// XANPhotoBrowser
+//
+// Created by Chen Xian'an on 12/17/10.
+// Copyright 2010 lazyapps.com. All rights reserved.
+//
+
+#import "XANThumbsViewController.h"
+#import "XANImageViewController.h"
+
+#define ROW_HEIGHT (kImageSize.height + kSpacing)
+
+@interface XANThumbsViewController()
+- (void)updateTableLayout;
+- (NSUInteger)numberOfRows;
+- (NSUInteger)capacityOfImagesInARow;
+- (NSUInteger)numberOfimagePathsForRow:(NSUInteger)row;
+- (void)updateImagesForCell:(XANThumbsCell *)cell;
+@end
+
+@implementation XANThumbsViewController
+@synthesize imagePaths;
+
+#pragma mark -
+#pragma mark View lifecycle
+
+- (id)initWithimagePaths:(NSArray *)theimagePaths
+{
+ if (self = [super initWithStyle:UITableViewStylePlain]){
+ imagePaths = [theimagePaths retain];
+ thumbImages = [[NSMutableArray alloc] initWithCapacity:[imagePaths count]];
+ for (NSInteger i=0; i<[imagePaths count]; i++){
+ [thumbImages addObject:[NSNull null]];
+ }
+
+ self.wantsFullScreenLayout = YES;
+ }
+
+ return self;
+}
+
+- (void)loadView
+{
+ [super loadView];
+
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ self.tableView.autoresizingMask =
+ UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self updateTableLayout];
+ self.tableView.rowHeight = ROW_HEIGHT;
+
+ self.navigationItem.title = @"XANImageBrowser";
+ self.navigationController.navigationBar.barStyle
+ = self.navigationController.toolbar.barStyle
+ = UIBarStyleBlack;
+ self.navigationController.navigationBar.translucent
+ = self.navigationController.toolbar.translucent
+ = YES;
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:YES];
+ [self.tableView reloadData];
+ [self updateTableLayout];
+ self.navigationController.toolbarHidden = YES;
+}
+
+// Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+}
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+ duration:(NSTimeInterval)duration
+{
+ [self updateTableLayout];
+ [self.tableView reloadData];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 1;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView
+ numberOfRowsInSection:(NSInteger)section
+{
+ return [self numberOfRows];
+}
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+
+ XANThumbsCell *cell = (XANThumbsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[XANThumbsCell alloc] initWithReuseIdentifier:CellIdentifier thumbDelegate:self] autorelease];
+ }
+
+ cell.capacityOfImages = [self capacityOfImagesInARow];
+ cell.numberOfImages = [self numberOfimagePathsForRow:indexPath.row];
+ cell.rowIndex = indexPath.row;
+ [self updateImagesForCell:cell];
+
+ return cell;
+}
+
+#pragma mark Table view delegate
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)didReceiveMemoryWarning
+{
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+
+ // Relinquish ownership any cached data, images, etc. that aren't in use.
+}
+
+- (void)viewDidUnload
+{
+ // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
+ // For example: self.myOutlet = nil;
+}
+
+
+- (void)dealloc
+{
+ [imagePaths release];
+ [super dealloc];
+}
+
+#pragma mark privates
+
+- (CGFloat)rowHeight
+{
+ return kImageSize.height + kSpacing;
+}
+
+- (void)updateTableLayout
+{
+ CGFloat barsHeight = 0;
+ if ([UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleBlackTranslucent && self.wantsFullScreenLayout) barsHeight += 20;
+ if (self.navigationController.navigationBar.translucent) barsHeight += self.navigationController.navigationBar.bounds.size.height;
+ self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(barsHeight, 0, 0, 0);
+ barsHeight += kSpacing;
+ self.tableView.contentInset = UIEdgeInsetsMake(barsHeight, 0, 0, 0);
+}
+
+- (NSUInteger)numberOfRows
+{
+ return [imagePaths count] / [self capacityOfImagesInARow] + 1;
+}
+
+- (NSUInteger)capacityOfImagesInARow
+{
+ return UIInterfaceOrientationIsPortrait(self.interfaceOrientation)
+ ? kCapacityOfImagesInARowPortrait
+ : kCapacityOfImagesInARowLandscape;
+}
+
+- (NSUInteger)numberOfimagePathsForRow:(NSUInteger)row
+{
+ if (row == [self numberOfRows]-1)
+ return [imagePaths count] % [self capacityOfImagesInARow];
+
+ return [self capacityOfImagesInARow];
+}
+
+- (void)updateImagesForCell:(XANThumbsCell *)cell
+{
+ for (NSUInteger column=0; column<cell.numberOfImages; column++){
+ NSUInteger realIndex = [self capacityOfImagesInARow]*cell.rowIndex + column;
+ NSObject *thumb = [thumbImages objectAtIndex:realIndex];
+
+ if ([thumb isEqual:[NSNull null]]){
+ dispatch_queue_t queue = dispatch_queue_create("name.xianan.chen.imagebrowser", NULL);
+ dispatch_async(queue, ^{
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagePaths objectAtIndex:realIndex]];
+ CGSize size = kImageSize;
+
+ if (image.size.width > image.size.height)
+ size.width = size.height * (image.size.width/image.size.height);
+ else
+ size.height = size.width * (image.size.height/image.size.width);
+
+ CGRect rect = CGRectZero;
+ rect.origin = CGPointZero;
+ rect.size = size;
+ UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
+ [image drawInRect:rect];
+ UIImage *thumbImage = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ [thumbImages replaceObjectAtIndex:realIndex withObject:thumbImage];
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [cell updateImage:thumbImage forColumn:column];
+ });
+
+ [image release];
+ });
+ } else {
+ [cell updateImage:(UIImage *)thumb forColumn:column];
+ }
+ }
+}
+
+#pragma mark XANThumbsCellDelegate
+- (void)didSelectPhotoAtIndex:(NSUInteger)index
+ inRow:(NSUInteger)rowIndex
+{
+ NSUInteger realIndex = [self capacityOfImagesInARow]*rowIndex + index;
+ XANImageViewController *ivc = [[XANImageViewController alloc] initWithImagePaths:imagePaths initialImageIndex:realIndex];
+ [self.navigationController pushViewController:ivc animated:YES];
+ [ivc release];
+}
+
+@end
+
9 LICENSE
@@ -0,0 +1,9 @@
+Copyright (c) 2010, Chen Xian'an.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of Chen Xian'an nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
422 MainWindow.xib
@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10H574</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.35</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="302016328">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUICustomObject" id="664661524">
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIWindow" id="380026005">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">1316</int>
+ <object class="NSPSMatrix" key="NSFrameMatrix"/>
+ <string key="NSFrameSize">{320, 480}</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIResizesToFullScreen">YES</bool>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="664661524"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="380026005"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="380026005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="664661524"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="302016328"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBAttributePlaceholdersKey</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>3.CustomClassName</string>
+ <string>3.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIApplication</string>
+ <string>UIResponder</string>
+ <object class="NSMutableDictionary">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <string>{{673, 376}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>XANAppDelegate</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">16</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIWindow</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">XANAppDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>navigationController</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UINavigationController</string>
+ <string>UIWindow</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>navigationController</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">navigationController</string>
+ <string key="candidateClassName">UINavigationController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">window</string>
+ <string key="candidateClassName">UIWindow</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/XANAppDelegate.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="48103097">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIApplication</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIApplication.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="720195805">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="48103097"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <reference key="sourceIdentifier" ref="720195805"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIWindow</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIWindow.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">XANPhotoBrowser.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
13 README.textile
@@ -0,0 +1,13 @@
+h1=. XANImageBrowser
+
+h2. Introduction
+
+p. Photos.app like image browser.
+
+h2. Requirements
+
+p. iOS 4.0+
+
+h2. How to use it in your project
+
+p. Open the project, drag all the files inside Classes group except XANAppDelegate.h(m). Take a look at XANAppDelegate.m to learn how to use.
32 XAN-Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+ <key>UIStatusBarStyle</key>
+ <string>UIStatusBarStyleBlackTranslucent</string>
+</dict>
+</plist>
385 XANImageBrowser.xcodeproj/project.pbxproj
@@ -0,0 +1,385 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1D3623260D0F684500981E51 /* XANAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* XANAppDelegate.m */; };
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
+ 2338424F12BE24D400B5ECB5 /* arrow_left.png in Resources */ = {isa = PBXBuildFile; fileRef = 2338424B12BE24D400B5ECB5 /* arrow_left.png */; };
+ 2338425012BE24D400B5ECB5 /* arrow_left@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2338424C12BE24D400B5ECB5 /* arrow_left@2x.png */; };
+ 2338425112BE24D400B5ECB5 /* arrow_right.png in Resources */ = {isa = PBXBuildFile; fileRef = 2338424D12BE24D400B5ECB5 /* arrow_right.png */; };
+ 2338425212BE24D400B5ECB5 /* arrow_right@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2338424E12BE24D400B5ECB5 /* arrow_right@2x.png */; };
+ 233D231A12BB9BA1000AEFE4 /* XANThumbsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 233D231812BB9BA1000AEFE4 /* XANThumbsViewController.m */; };
+ 233D233412BBAAAF000AEFE4 /* 0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232612BBAAAF000AEFE4 /* 0.jpg */; };
+ 233D233512BBAAAF000AEFE4 /* 1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232712BBAAAF000AEFE4 /* 1.jpg */; };
+ 233D233612BBAAAF000AEFE4 /* 2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232812BBAAAF000AEFE4 /* 2.jpg */; };
+ 233D233712BBAAAF000AEFE4 /* 3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232912BBAAAF000AEFE4 /* 3.jpg */; };
+ 233D233812BBAAAF000AEFE4 /* 4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232A12BBAAAF000AEFE4 /* 4.jpg */; };
+ 233D233912BBAAAF000AEFE4 /* 5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232B12BBAAAF000AEFE4 /* 5.jpg */; };
+ 233D233A12BBAAAF000AEFE4 /* 6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232C12BBAAAF000AEFE4 /* 6.jpg */; };
+ 233D233B12BBAAAF000AEFE4 /* 7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232D12BBAAAF000AEFE4 /* 7.jpg */; };
+ 233D233C12BBAAAF000AEFE4 /* 8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232E12BBAAAF000AEFE4 /* 8.jpg */; };
+ 233D233D12BBAAAF000AEFE4 /* 9.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D232F12BBAAAF000AEFE4 /* 9.jpg */; };
+ 233D233E12BBAAAF000AEFE4 /* 10.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D233012BBAAAF000AEFE4 /* 10.jpg */; };
+ 233D233F12BBAAAF000AEFE4 /* 11.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D233112BBAAAF000AEFE4 /* 11.jpg */; };
+ 233D234012BBAAAF000AEFE4 /* 12.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D233212BBAAAF000AEFE4 /* 12.jpg */; };
+ 233D234112BBAAAF000AEFE4 /* 13.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D233312BBAAAF000AEFE4 /* 13.jpg */; };
+ 233D234512BBAF2A000AEFE4 /* XANThumbsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 233D234412BBAF2A000AEFE4 /* XANThumbsCell.m */; };
+ 233D239F12BBCB69000AEFE4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 233D239E12BBCB69000AEFE4 /* QuartzCore.framework */; };
+ 233D23F012BBCF27000AEFE4 /* 14.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23E712BBCF27000AEFE4 /* 14.jpg */; };
+ 233D23F112BBCF27000AEFE4 /* 15.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23E812BBCF27000AEFE4 /* 15.jpg */; };
+ 233D23F212BBCF27000AEFE4 /* 16.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23E912BBCF27000AEFE4 /* 16.jpg */; };
+ 233D23F312BBCF27000AEFE4 /* 17.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23EA12BBCF27000AEFE4 /* 17.jpg */; };
+ 233D23F412BBCF27000AEFE4 /* 18.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23EB12BBCF27000AEFE4 /* 18.jpg */; };
+ 233D23F512BBCF27000AEFE4 /* 19.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23EC12BBCF27000AEFE4 /* 19.jpg */; };
+ 233D23F612BBCF27000AEFE4 /* 20.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23ED12BBCF27000AEFE4 /* 20.jpg */; };
+ 233D23F712BBCF27000AEFE4 /* 21.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23EE12BBCF27000AEFE4 /* 21.jpg */; };
+ 233D23F812BBCF27000AEFE4 /* 22.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 233D23EF12BBCF27000AEFE4 /* 22.jpg */; };
+ 23CA998D12BC7BDE001527BE /* XANImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CA998C12BC7BDE001527BE /* XANImageViewController.m */; };
+ 23CA9A1F12BCCB3F001527BE /* XANImageScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CA9A1E12BCCB3F001527BE /* XANImageScrollView.m */; };
+ 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; };
+ 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D3623240D0F684500981E51 /* XANAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XANAppDelegate.h; sourceTree = "<group>"; };
+ 1D3623250D0F684500981E51 /* XANAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XANAppDelegate.m; sourceTree = "<group>"; };
+ 1D6058910D05DD3D006BFB54 /* XANImageBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XANImageBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 2338424B12BE24D400B5ECB5 /* arrow_left.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = arrow_left.png; sourceTree = "<group>"; };
+ 2338424C12BE24D400B5ECB5 /* arrow_left@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_left@2x.png"; sourceTree = "<group>"; };
+ 2338424D12BE24D400B5ECB5 /* arrow_right.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = arrow_right.png; sourceTree = "<group>"; };
+ 2338424E12BE24D400B5ECB5 /* arrow_right@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "arrow_right@2x.png"; sourceTree = "<group>"; };
+ 233D231712BB9BA1000AEFE4 /* XANThumbsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XANThumbsViewController.h; sourceTree = "<group>"; };
+ 233D231812BB9BA1000AEFE4 /* XANThumbsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XANThumbsViewController.m; sourceTree = "<group>"; };
+ 233D232612BBAAAF000AEFE4 /* 0.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 0.jpg; sourceTree = "<group>"; };
+ 233D232712BBAAAF000AEFE4 /* 1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 1.jpg; sourceTree = "<group>"; };
+ 233D232812BBAAAF000AEFE4 /* 2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 2.jpg; sourceTree = "<group>"; };
+ 233D232912BBAAAF000AEFE4 /* 3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 3.jpg; sourceTree = "<group>"; };
+ 233D232A12BBAAAF000AEFE4 /* 4.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 4.jpg; sourceTree = "<group>"; };
+ 233D232B12BBAAAF000AEFE4 /* 5.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 5.jpg; sourceTree = "<group>"; };
+ 233D232C12BBAAAF000AEFE4 /* 6.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 6.jpg; sourceTree = "<group>"; };
+ 233D232D12BBAAAF000AEFE4 /* 7.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 7.jpg; sourceTree = "<group>"; };
+ 233D232E12BBAAAF000AEFE4 /* 8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 8.jpg; sourceTree = "<group>"; };
+ 233D232F12BBAAAF000AEFE4 /* 9.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 9.jpg; sourceTree = "<group>"; };
+ 233D233012BBAAAF000AEFE4 /* 10.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 10.jpg; sourceTree = "<group>"; };
+ 233D233112BBAAAF000AEFE4 /* 11.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 11.jpg; sourceTree = "<group>"; };
+ 233D233212BBAAAF000AEFE4 /* 12.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 12.jpg; sourceTree = "<group>"; };
+ 233D233312BBAAAF000AEFE4 /* 13.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 13.jpg; sourceTree = "<group>"; };
+ 233D234312BBAF2A000AEFE4 /* XANThumbsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XANThumbsCell.h; sourceTree = "<group>"; };
+ 233D234412BBAF2A000AEFE4 /* XANThumbsCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XANThumbsCell.m; sourceTree = "<group>"; };
+ 233D239E12BBCB69000AEFE4 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ 233D23E712BBCF27000AEFE4 /* 14.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 14.jpg; sourceTree = "<group>"; };
+ 233D23E812BBCF27000AEFE4 /* 15.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 15.jpg; sourceTree = "<group>"; };
+ 233D23E912BBCF27000AEFE4 /* 16.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 16.jpg; sourceTree = "<group>"; };
+ 233D23EA12BBCF27000AEFE4 /* 17.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 17.jpg; sourceTree = "<group>"; };
+ 233D23EB12BBCF27000AEFE4 /* 18.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 18.jpg; sourceTree = "<group>"; };
+ 233D23EC12BBCF27000AEFE4 /* 19.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 19.jpg; sourceTree = "<group>"; };
+ 233D23ED12BBCF27000AEFE4 /* 20.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 20.jpg; sourceTree = "<group>"; };
+ 233D23EE12BBCF27000AEFE4 /* 21.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 21.jpg; sourceTree = "<group>"; };
+ 233D23EF12BBCF27000AEFE4 /* 22.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 22.jpg; sourceTree = "<group>"; };
+ 23CA998B12BC7BDE001527BE /* XANImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XANImageViewController.h; sourceTree = "<group>"; };
+ 23CA998C12BC7BDE001527BE /* XANImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XANImageViewController.m; sourceTree = "<group>"; };
+ 23CA9A1D12BCCB3F001527BE /* XANImageScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XANImageScrollView.h; sourceTree = "<group>"; };
+ 23CA9A1E12BCCB3F001527BE /* XANImageScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XANImageScrollView.m; sourceTree = "<group>"; };
+ 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 28A0AAE50D9B0CCF005BE974 /* XAN_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XAN_Prefix.pch; sourceTree = "<group>"; };
+ 28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* XAN-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "XAN-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+ 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
+ 233D239F12BBCB69000AEFE4 /* QuartzCore.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 1D3623240D0F684500981E51 /* XANAppDelegate.h */,
+ 1D3623250D0F684500981E51 /* XANAppDelegate.m */,
+ 233D231712BB9BA1000AEFE4 /* XANThumbsViewController.h */,
+ 233D231812BB9BA1000AEFE4 /* XANThumbsViewController.m */,
+ 233D234312BBAF2A000AEFE4 /* XANThumbsCell.h */,
+ 233D234412BBAF2A000AEFE4 /* XANThumbsCell.m */,
+ 23CA998B12BC7BDE001527BE /* XANImageViewController.h */,
+ 23CA998C12BC7BDE001527BE /* XANImageViewController.m */,
+ 23CA9A1D12BCCB3F001527BE /* XANImageScrollView.h */,
+ 23CA9A1E12BCCB3F001527BE /* XANImageScrollView.m */,
+ );
+ path = Classes;
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* XANImageBrowser.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 28A0AAE50D9B0CCF005BE974 /* XAN_Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 2338424B12BE24D400B5ECB5 /* arrow_left.png */,
+ 2338424C12BE24D400B5ECB5 /* arrow_left@2x.png */,
+ 2338424D12BE24D400B5ECB5 /* arrow_right.png */,
+ 2338424E12BE24D400B5ECB5 /* arrow_right@2x.png */,
+ 233D232612BBAAAF000AEFE4 /* 0.jpg */,
+ 233D232712BBAAAF000AEFE4 /* 1.jpg */,
+ 233D232812BBAAAF000AEFE4 /* 2.jpg */,
+ 233D232912BBAAAF000AEFE4 /* 3.jpg */,
+ 233D232A12BBAAAF000AEFE4 /* 4.jpg */,
+ 233D232B12BBAAAF000AEFE4 /* 5.jpg */,
+ 233D232C12BBAAAF000AEFE4 /* 6.jpg */,
+ 233D232D12BBAAAF000AEFE4 /* 7.jpg */,
+ 233D232E12BBAAAF000AEFE4 /* 8.jpg */,
+ 233D232F12BBAAAF000AEFE4 /* 9.jpg */,
+ 233D233012BBAAAF000AEFE4 /* 10.jpg */,
+ 233D233112BBAAAF000AEFE4 /* 11.jpg */,
+ 233D233212BBAAAF000AEFE4 /* 12.jpg */,
+ 233D233312BBAAAF000AEFE4 /* 13.jpg */,
+ 233D23E712BBCF27000AEFE4 /* 14.jpg */,
+ 233D23E812BBCF27000AEFE4 /* 15.jpg */,
+ 233D23E912BBCF27000AEFE4 /* 16.jpg */,
+ 233D23EA12BBCF27000AEFE4 /* 17.jpg */,
+ 233D23EB12BBCF27000AEFE4 /* 18.jpg */,
+ 233D23EC12BBCF27000AEFE4 /* 19.jpg */,
+ 233D23ED12BBCF27000AEFE4 /* 20.jpg */,
+ 233D23EE12BBCF27000AEFE4 /* 21.jpg */,
+ 233D23EF12BBCF27000AEFE4 /* 22.jpg */,
+ 28AD735F0D9D9599002E5188 /* MainWindow.xib */,
+ 8D1107310486CEB800E47090 /* XAN-Info.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
+ 233D239E12BBCB69000AEFE4 /* QuartzCore.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* XANImageBrowser */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "XANImageBrowser" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = XANImageBrowser;
+ productName = XAN;
+ productReference = 1D6058910D05DD3D006BFB54 /* XANImageBrowser.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XANImageBrowser" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ en,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* XANImageBrowser */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */,
+ 233D233412BBAAAF000AEFE4 /* 0.jpg in Resources */,
+ 233D233512BBAAAF000AEFE4 /* 1.jpg in Resources */,
+ 233D233612BBAAAF000AEFE4 /* 2.jpg in Resources */,
+ 233D233712BBAAAF000AEFE4 /* 3.jpg in Resources */,
+ 233D233812BBAAAF000AEFE4 /* 4.jpg in Resources */,
+ 233D233912BBAAAF000AEFE4 /* 5.jpg in Resources */,
+ 233D233A12BBAAAF000AEFE4 /* 6.jpg in Resources */,
+ 233D233B12BBAAAF000AEFE4 /* 7.jpg in Resources */,
+ 233D233C12BBAAAF000AEFE4 /* 8.jpg in Resources */,
+ 233D233D12BBAAAF000AEFE4 /* 9.jpg in Resources */,
+ 233D233E12BBAAAF000AEFE4 /* 10.jpg in Resources */,
+ 233D233F12BBAAAF000AEFE4 /* 11.jpg in Resources */,
+ 233D234012BBAAAF000AEFE4 /* 12.jpg in Resources */,
+ 233D234112BBAAAF000AEFE4 /* 13.jpg in Resources */,
+ 233D23F012BBCF27000AEFE4 /* 14.jpg in Resources */,
+ 233D23F112BBCF27000AEFE4 /* 15.jpg in Resources */,
+ 233D23F212BBCF27000AEFE4 /* 16.jpg in Resources */,
+ 233D23F312BBCF27000AEFE4 /* 17.jpg in Resources */,
+ 233D23F412BBCF27000AEFE4 /* 18.jpg in Resources */,
+ 233D23F512BBCF27000AEFE4 /* 19.jpg in Resources */,
+ 233D23F612BBCF27000AEFE4 /* 20.jpg in Resources */,
+ 233D23F712BBCF27000AEFE4 /* 21.jpg in Resources */,
+ 233D23F812BBCF27000AEFE4 /* 22.jpg in Resources */,
+ 2338424F12BE24D400B5ECB5 /* arrow_left.png in Resources */,
+ 2338425012BE24D400B5ECB5 /* arrow_left@2x.png in Resources */,
+ 2338425112BE24D400B5ECB5 /* arrow_right.png in Resources */,
+ 2338425212BE24D400B5ECB5 /* arrow_right@2x.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1D60589B0D05DD56006BFB54 /* main.m in Sources */,
+ 1D3623260D0F684500981E51 /* XANAppDelegate.m in Sources */,
+ 233D231A12BB9BA1000AEFE4 /* XANThumbsViewController.m in Sources */,
+ 233D234512BBAF2A000AEFE4 /* XANThumbsCell.m in Sources */,
+ 23CA998D12BC7BDE001527BE /* XANImageViewController.m in Sources */,
+ 23CA9A1F12BCCB3F001527BE /* XANImageScrollView.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = XAN_Prefix.pch;
+ INFOPLIST_FILE = "XAN-Info.plist";
+ PRODUCT_NAME = XANImageBrowser;
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = XAN_Prefix.pch;
+ INFOPLIST_FILE = "XAN-Info.plist";
+ PRODUCT_NAME = XANImageBrowser;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "XANImageBrowser" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "XANImageBrowser" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
1,443 XANImageBrowser.xcodeproj/xan.mode1v3
@@ -0,0 +1,1443 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>BundlePath</key>
+ <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1v3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>233D22F312BB9B15000AEFE4</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1v3</string>
+ <key>MajorVersion</key>
+ <integer>33</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-combo-popup</string>
+ <string>action</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>build-and-go</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>get-info</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>com.apple.pbx.toolbar.searchfield</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>241</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>080E96DDFE201D6D7F000001</string>
+ <string>29B97323FDCFA39411CA2CEA</string>
+ <string>19C28FACFE9D520D11CA2CBB</string>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>5</integer>
+ <integer>1</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {241, 914}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {258, 932}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>241</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>904 189 1123 973 0 0 2560 1418 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>258pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>XANThumbsViewController.m</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>XANThumbsViewController.m</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>23B2930A12BE45430003805C</string>
+ <key>history</key>
+ <array>
+ <string>2351C44112BC423700E340A1</string>
+ <string>2351C44212BC423700E340A1</string>
+ <string>23CA999612BC7C55001527BE</string>
+ <string>23CA99A512BC7CBC001527BE</string>
+ <string>23CA9A1212BCC49F001527BE</string>
+ <string>2338413D12BDC28500B5ECB5</string>
+ <string>2338413E12BDC28500B5ECB5</string>
+ <string>2338413F12BDC28500B5ECB5</string>
+ <string>2338414012BDC28500B5ECB5</string>
+ <string>2338414112BDC28500B5ECB5</string>
+ <string>2338414212BDC28500B5ECB5</string>
+ <string>2338414312BDC28500B5ECB5</string>
+ <string>2338414412BDC28500B5ECB5</string>
+ <string>2338414512BDC28500B5ECB5</string>
+ <string>2338414612BDC28500B5ECB5</string>
+ <string>2338414712BDC28500B5ECB5</string>
+ <string>2338414812BDC28500B5ECB5</string>
+ <string>2338415412BDC4F800B5ECB5</string>
+ <string>233841A212BDE61E00B5ECB5</string>
+ <string>2338425512BE2A0100B5ECB5</string>
+ <string>2338425612BE2A0100B5ECB5</string>
+ <string>2338425712BE2A0100B5ECB5</string>
+ <string>2338425812BE2A0100B5ECB5</string>
+ <string>2338425912BE2A0100B5ECB5</string>
+ <string>233842A012BE351500B5ECB5</string>
+ <string>23B2930712BE45430003805C</string>
+ <string>23B2930812BE45430003805C</string>
+ <string>23B2930912BE45430003805C</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {860, 683}}</string>
+ <key>RubberWindowFrame</key>
+ <string>904 189 1123 973 0 0 2560 1418 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>683pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>