├── CustomImagePicker.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── CustomImagePicker.xccheckout
│ └── xcuserdata
│ │ └── pnanda.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── pnanda.xcuserdatad
│ └── xcschemes
│ ├── CustomImagePicker.xcscheme
│ └── xcschememanagement.plist
├── CustomImagePicker
├── AppDelegate.h
├── AppDelegate.m
├── CameraCell.h
├── CameraCell.m
├── CameraCell.xib
├── CameraCell_5.xib
├── CameraFocusSquare.h
├── CameraFocusSquare.m
├── ColorUtil.h
├── ColorUtil.m
├── CustomeImagePicker.h
├── CustomeImagePicker.m
├── CustomeImagePicker.xib
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── OLGhostAlertView.h
├── OLGhostAlertView.m
├── PhotoCell.h
├── PhotoCell.m
├── PhotoCell.xib
├── PhotoPickerCell.h
├── PhotoPickerCell.m
├── PhotoPickerCell.xib
├── PhotoPickerCell_5.xib
├── RNActivityView.h
├── RNActivityView.m
├── UIView+RNActivityView.h
├── UIView+RNActivityView.m
├── ViewController.h
├── ViewController.m
├── ViewController.xib
├── YCameraViewController.h
├── YCameraViewController.m
├── YCameraViewController.xib
└── main.m
├── CustomImagePickerTests
├── CustomImagePickerTests.m
└── Info.plist
├── Header.h
├── LICENSE
├── README.md
├── images
├── camera.png
├── cameraorange.png
├── discard.png
├── discard@2x.png
├── flash-auto.png
├── flash-auto@2x.png
├── flash-off.png
├── flash-off@2x.png
├── flash.png
├── flash@2x.png
├── focus-crosshair.png
├── focus-crosshair@2x.png
├── front-camera.png
├── front-camera@2x.png
├── screenshot.jpg
├── take-snap.png
├── take-snap@2x.png
└── tick.png
└── screenshot.jpg
/CustomImagePicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomImagePicker.xcodeproj/project.xcworkspace/xcshareddata/CustomImagePicker.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 27D9E7EA-F518-42A6-ADB4-CE3A7CF95D29
9 | IDESourceControlProjectName
10 | CustomImagePicker
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | B337A9954EDE3E34A0359B7F2DB649E2E7D266F5
14 | https://github.com/cspnanda/CustomImagePicker.git
15 |
16 | IDESourceControlProjectPath
17 | CustomImagePicker.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | B337A9954EDE3E34A0359B7F2DB649E2E7D266F5
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/cspnanda/CustomImagePicker.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | B337A9954EDE3E34A0359B7F2DB649E2E7D266F5
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | B337A9954EDE3E34A0359B7F2DB649E2E7D266F5
36 | IDESourceControlWCCName
37 | CustomImagePicker
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/CustomImagePicker.xcodeproj/project.xcworkspace/xcuserdata/pnanda.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/CustomImagePicker.xcodeproj/project.xcworkspace/xcuserdata/pnanda.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CustomImagePicker.xcodeproj/xcuserdata/pnanda.xcuserdatad/xcschemes/CustomImagePicker.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/CustomImagePicker.xcodeproj/xcuserdata/pnanda.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CustomImagePicker.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 18B38D0D1A5B17FC005915E3
16 |
17 | primary
18 |
19 |
20 | 18B38D261A5B17FC005915E3
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CustomImagePicker/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ViewController.h"
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (strong, nonatomic) UIWindow *window;
15 |
16 |
17 | @end
18 |
19 |
--------------------------------------------------------------------------------
/CustomImagePicker/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
21 |
22 |
23 | ViewController *livc = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
24 |
25 | self.window.rootViewController = livc;
26 | [self.window makeKeyAndVisible];
27 | return YES;
28 |
29 |
30 |
31 |
32 | return YES;
33 | }
34 |
35 | - (void)applicationWillResignActive:(UIApplication *)application {
36 | // 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.
37 | // 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.
38 | }
39 |
40 | - (void)applicationDidEnterBackground:(UIApplication *)application {
41 | // 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.
42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
43 | }
44 |
45 | - (void)applicationWillEnterForeground:(UIApplication *)application {
46 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
47 | }
48 |
49 | - (void)applicationDidBecomeActive:(UIApplication *)application {
50 | // 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.
51 | }
52 |
53 | - (void)applicationWillTerminate:(UIApplication *)application {
54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/CustomImagePicker/CameraCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.h
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "Header.h"
12 |
13 | @interface CameraCell : UICollectionViewCell
14 | - (void) setAsset:(ALAsset *)asset;
15 | - (void) setImage:(UIImage *)image;
16 | - (UIImageView*) getImageView;
17 | -(void) performSelectionAnimations;
18 | -(void) hideTick;
19 | -(void) showTick;
20 | @property(nonatomic, strong) ALAsset *asset;
21 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/CameraCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.m
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import "CameraCell.h"
10 |
11 | @interface CameraCell ()
12 | // 1
13 | @property(nonatomic, weak) IBOutlet UIImageView *photoImageView;
14 | @property(nonatomic, weak) IBOutlet UIImageView *tickView;
15 |
16 | @end
17 |
18 | @implementation CameraCell
19 | - (UIImageView*) getImageView;
20 | {
21 | return self.photoImageView;
22 | }
23 | - (id)initWithFrame:(CGRect)frame {
24 |
25 | self = [super initWithFrame:frame];
26 |
27 | if (self) {
28 | // Initialization code
29 | NSArray *arrayOfViews = Nil;
30 | if(IS_IPHONE_6||IS_IPHONE_6P)
31 | arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CameraCell" owner:self options:nil];
32 | else
33 | arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CameraCell_5" owner:self options:nil];
34 |
35 |
36 | if ([arrayOfViews count] < 1) {
37 | return nil;
38 | }
39 |
40 | if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
41 | return nil;
42 | }
43 |
44 | self = [arrayOfViews objectAtIndex:0];
45 |
46 | }
47 |
48 | return self;
49 |
50 | }
51 |
52 | -(void) showTick
53 | {
54 | [self.tickView setHidden:NO];
55 | }
56 | -(void) hideTick
57 | {
58 | [self.tickView setHidden:YES];
59 | }
60 | - (void) setAsset:(ALAsset *)asset
61 | {
62 | // 2
63 | _asset = asset;
64 | self.photoImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
65 | }
66 | - (void) setImage:(UIImage *)image
67 | {
68 | [self.photoImageView setImage:image];
69 | }
70 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/CameraCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CustomImagePicker/CameraCell_5.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CustomImagePicker/CameraFocusSquare.h:
--------------------------------------------------------------------------------
1 | //
2 | // CameraFocusSquare.h
3 | //
4 | // Created by Prasanna Nanda on 6/11/15.
5 | // Copyright (c) 2015 iosrecipe. All rights reserved.
6 | //
7 |
8 | #import
9 | #import "ColorUtil.h"
10 | @interface CameraFocusSquare : UIView
11 | @end
12 |
--------------------------------------------------------------------------------
/CustomImagePicker/CameraFocusSquare.m:
--------------------------------------------------------------------------------
1 | //
2 | // CameraFocusSquare.m
3 | //
4 | // Created by Prasanna Nanda on 6/11/15.
5 | // Copyright (c) 2015 iosrecipe. All rights reserved.
6 | //
7 |
8 | #import "CameraFocusSquare.h"
9 | #import
10 |
11 | const float squareLength = 80.0f;
12 | @implementation CameraFocusSquare
13 |
14 | - (id)initWithFrame:(CGRect)frame
15 | {
16 | self = [super initWithFrame:frame];
17 | if (self) {
18 | // Initialization code
19 |
20 | [self setBackgroundColor:[UIColor clearColor]];
21 | [self.layer setBorderWidth:2.0];
22 | [self.layer setCornerRadius:4.0];
23 | [self.layer setBorderColor:[UIColor whiteColor].CGColor];
24 |
25 | CABasicAnimation* selectionAnimation = [CABasicAnimation
26 | animationWithKeyPath:@"borderColor"];
27 | selectionAnimation.toValue = (id)[ColorUtil colorFromHexString:@"#ff7f00" withAlpha:1.0].CGColor;
28 | selectionAnimation.repeatCount = 8;
29 | [self.layer addAnimation:selectionAnimation
30 | forKey:@"selectionAnimation"];
31 |
32 | }
33 | return self;
34 | }
35 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/ColorUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // ColorUtil.h
3 | //
4 | // Created by İlyas Doğruer
5 | //
6 |
7 | #import
8 | #import
9 | #import
10 | #import
11 | #import
12 | #import
13 |
14 | @interface ColorUtil : NSObject
15 |
16 | +(UIColor *)colorFromHexString:(NSString *)hexString withAlpha:(float)alpha;
17 | +(UIColor *)colorFromHexValue:(UInt32)hexValue withAlpha:(float)alpha;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CustomImagePicker/ColorUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // ColorUtil.m
3 | //
4 | // Created by İlyas Doğruer
5 | //
6 |
7 | #import "ColorUtil.h"
8 |
9 | @implementation ColorUtil
10 |
11 | +(UIColor *)colorFromHexString:(NSString *)hexString withAlpha:(float)alpha {
12 | unsigned rgbValue = 0;
13 | NSScanner *scanner = [NSScanner scannerWithString:hexString];
14 | [scanner setScanLocation:1];
15 | [scanner scanHexInt:&rgbValue];
16 |
17 | CGFloat r = ((rgbValue & 0xFF0000) >> 16)/255.0f;
18 | CGFloat g = ((rgbValue & 0xFF00) >> 8)/255.0f;
19 | CGFloat b = (rgbValue & 0xFF)/255.0f;
20 |
21 | return [UIColor colorWithRed:r green:g blue:b alpha:alpha];
22 | }
23 |
24 | +(UIColor *)colorFromHexValue:(UInt32)hexValue withAlpha:(float)alpha {
25 | int redValue = (hexValue >> 16) & 0xFF;
26 | int greenValue = (hexValue >> 8) & 0xFF;
27 | int blueValue = (hexValue) & 0xFF;
28 |
29 | CGFloat r = redValue / 255.0f;
30 | CGFloat g = greenValue / 255.0f;
31 | CGFloat b = blueValue / 255.0f;
32 |
33 | return [UIColor colorWithRed:r green:g blue:b alpha:alpha];
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/CustomImagePicker/CustomeImagePicker.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomeImagePicker.h
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "PhotoPickerCell.h"
12 | #import "CameraCell.h"
13 | #import "Header.h"
14 | #import "OLGhostAlertView.h"
15 | #import "YCameraViewController.h"
16 | #import
17 | #import
18 |
19 | @protocol CustomeImagePickerDelegate
20 |
21 | -(void)imageSelected:(NSArray*)arrayOfImages;
22 | -(void)imageSelectionCancelled;
23 |
24 | @end
25 |
26 |
27 |
28 | @interface CustomeImagePicker : UIViewController
29 | {
30 | AVCaptureSession *session;
31 | AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
32 | AVCaptureStillImageOutput *stillImageOutput;
33 | UIImage *croppedImageWithoutOrientation;
34 |
35 | }
36 |
37 | @property(nonatomic, weak) IBOutlet UICollectionView *collectionView;
38 | @property(nonatomic, strong) IBOutlet UICollectionView *nearByCollectionView;
39 |
40 | @property(nonatomic, weak) IBOutlet UIButton *skipButton;
41 | @property(nonatomic, weak) IBOutlet UIButton *nextButton;
42 | @property (nonatomic, strong) NSIndexPath *selectedItemIndexPath;
43 | @property (nonatomic, assign) NSInteger maxPhotos;
44 | @property (nonatomic,strong) IBOutlet NSLayoutConstraint *distanceFromButton;
45 |
46 | @property (nonatomic, strong) NSDictionary *whereamI;
47 | //@property (nonatomic, strong) NSMutableArray *selectedImages;
48 | //@property (nonatomic, strong) NSMutableArray *disselectedImages;
49 | @property (nonatomic, assign) BOOL hideSkipButton;
50 | @property (nonatomic, assign) BOOL hideNextButton;
51 | @property (nonatomic, strong) NSMutableArray *highLightThese;
52 | @property(nonatomic,weak) id delegate;
53 | // @property(nonatomic, weak) IBOutlet UIButton *nextButton;
54 | @property (nonatomic,strong) CLLocation *currentUserLocation;
55 | @property (nonatomic,assign) BOOL showOnlyPhotosWithGPS;
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | @end
64 |
--------------------------------------------------------------------------------
/CustomImagePicker/CustomeImagePicker.m:
--------------------------------------------------------------------------------
1 | //
2 | // CustomeImagePicker.m
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import "CustomeImagePicker.h"
10 | #import "UIView+RNActivityView.h"
11 | @interface CustomeImagePicker ()
12 | @property(nonatomic, strong) NSArray *assets;
13 | // @property(nonatomic,strong) UIImage *selectedImage;
14 | @end
15 |
16 | @implementation CustomeImagePicker
17 | @synthesize whereamI,skipButton,nextButton,hideNextButton,hideSkipButton,highLightThese,maxPhotos,distanceFromButton,nearByCollectionView,currentUserLocation,showOnlyPhotosWithGPS;
18 | // @synthesize selectedImages,disselectedImages;
19 |
20 | -(BOOL) checkForCamera
21 | {
22 | AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
23 | if(authStatus == AVAuthorizationStatusAuthorized) {
24 | // do your logic
25 | return YES;
26 | }
27 | return NO;
28 | }
29 | -(void) viewWillAppear:(BOOL)animated
30 | {
31 | [super viewWillAppear:animated];
32 | if(highLightThese == Nil)
33 | highLightThese = [[NSMutableArray alloc] init];
34 |
35 | }
36 | -(void) viewDidDisappear:(BOOL)animated
37 | {
38 | [super viewDidDisappear:animated];
39 | [session stopRunning];
40 | }
41 | -(void) viewDidAppear:(BOOL)animated
42 | {
43 | [super viewDidAppear:animated];
44 | // if(showOnlyPhotosWithGPS==NO && [self checkForCamera] == YES)
45 | [self performSelector:@selector(initializeCamera) withObject:nil afterDelay:0.1];
46 | }
47 |
48 | - (void)viewDidLoad
49 | {
50 | [super viewDidLoad];
51 | if(hideSkipButton)
52 | {
53 | [skipButton setHidden:YES];
54 | }
55 | if(hideNextButton)
56 | {
57 | [nextButton setHidden:YES];
58 | }
59 | if([highLightThese count]>=1)
60 | [nextButton setHidden:NO];
61 | else
62 | [nextButton setHidden:YES];
63 | // selectedImages = [[NSMutableArray alloc] init];
64 | // disselectedImages = [[NSMutableArray alloc] init];
65 | [self.collectionView registerClass:[PhotoPickerCell class] forCellWithReuseIdentifier:@"PhotoPickerCell"];
66 | [self.collectionView registerClass:[CameraCell class] forCellWithReuseIdentifier:@"CameraCell"];
67 |
68 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
69 | if(IS_IPHONE_6 || IS_IPHONE_6P)
70 | [flowLayout setItemSize:CGSizeMake(120, 120)];
71 | else
72 | [flowLayout setItemSize:CGSizeMake(100, 100)];
73 | [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
74 | [self.collectionView setCollectionViewLayout:flowLayout];
75 |
76 | _assets = [@[] mutableCopy];
77 | __block NSMutableArray *tmpAssets = [@[] mutableCopy];
78 | if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
79 | ALAsset *asset = [[ALAsset alloc] init];
80 | if(showOnlyPhotosWithGPS==NO)
81 | [tmpAssets insertObject:asset atIndex:0];
82 | }
83 | ALAssetsLibrary *assetsLibrary = [CustomeImagePicker defaultAssetsLibrary];
84 | [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
85 | [group setAssetsFilter:[ALAssetsFilter allPhotos]];
86 | [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
87 | if(result)
88 | {
89 | if(showOnlyPhotosWithGPS == YES)
90 | {
91 | if([result valueForProperty:ALAssetPropertyLocation])
92 | [tmpAssets addObject:result];
93 | }
94 | else
95 | [tmpAssets addObject:result];
96 | }
97 | }
98 | ];
99 |
100 | } failureBlock:^(NSError *error) {
101 | NSLog(@"Error loading images %@", error);
102 | if([ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusAuthorized)
103 | {
104 | [self displayErrorOnMainQueue:@"Photo Access Disabled" message:@"Please allow Photo Access in System Settings"];
105 | }
106 | }];
107 | self.assets = tmpAssets;
108 | dispatch_time_t popTime1 = dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC);
109 | dispatch_after(popTime1, dispatch_get_main_queue(), ^(void){
110 | if(showOnlyPhotosWithGPS==YES) {
111 | OLGhostAlertView *ghastly = [[OLGhostAlertView alloc] initWithTitle:@"Photos with Location" message: @"Only Photos with Location Information are shown here." timeout:2.0 dismissible:YES];
112 | [ghastly show];
113 | }
114 |
115 | [self.collectionView reloadData];
116 | });
117 |
118 | // });
119 | nextButton.layer.borderColor = [[UIColor whiteColor] CGColor];
120 | nextButton.layer.borderWidth = 1.0f;
121 | nextButton.layer.cornerRadius = 5.0f;
122 |
123 | skipButton.layer.borderColor = [[UIColor whiteColor] CGColor];
124 | skipButton.layer.borderWidth = 1.0f;
125 | skipButton.layer.cornerRadius = 5.0f;
126 |
127 | // dispatch_time_t popTime1 = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
128 | // dispatch_after(popTime1, dispatch_get_main_queue(), ^(void){
129 | // [self addLiveCamera];
130 | // });
131 | }
132 | - (void)displayErrorOnMainQueue:(NSString*) heading message:(NSString *)message
133 | {
134 | dispatch_async(dispatch_get_main_queue(), ^(void) {
135 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:heading
136 | message:message
137 | delegate:nil
138 | cancelButtonTitle:@"Dismiss"
139 | otherButtonTitles:nil];
140 | [alertView show];
141 | [alertView release];
142 | });
143 | }
144 |
145 | -(void) populateNearbyPhotos {
146 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
147 | ALAssetsLibrary *assetsLibrary = [CustomeImagePicker defaultAssetsLibrary];
148 | [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
149 | [group setAssetsFilter:[ALAssetsFilter allPhotos]];
150 | [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
151 | if(result)
152 | {
153 | NSDictionary *metadata = [[result defaultRepresentation] metadata];
154 | NSMutableDictionary *GPSDictionary = [metadata objectForKey:(NSString *)kCGImagePropertyGPSDictionary];
155 | if(GPSDictionary)
156 | {
157 |
158 | CLLocation *locFromPhoto = [[CLLocation alloc] initWithLatitude:[[GPSDictionary objectForKey:@"Latitude"] doubleValue] longitude:[[GPSDictionary objectForKey:@"Longitude"] doubleValue]];
159 |
160 |
161 | CLLocationCoordinate2D loc = CLLocationCoordinate2DMake([[[whereamI objectForKey:@"location"] objectForKey:@"latitude"] doubleValue], [[[whereamI objectForKey:@"location"] objectForKey:@"longitude"] doubleValue]);
162 | CLLocation *userLocation = [[CLLocation alloc] initWithLatitude:loc.latitude longitude:loc.longitude];
163 |
164 |
165 | CLLocationDistance distance = [locFromPhoto distanceFromLocation:userLocation];
166 | NSLog(@"%f",distance);
167 | if(distance < 1000)
168 | {
169 | NSLog(@"Nearby");
170 | }
171 |
172 | }
173 | }
174 | }
175 | ];
176 |
177 | } failureBlock:^(NSError *error) {
178 | }];
179 | });
180 | }
181 |
182 |
183 |
184 |
185 |
186 | -(void) addLiveCamera
187 | {
188 | NSIndexPath *ip = [[NSIndexPath alloc] initWithIndex:0];
189 | UICollectionViewCell *firstCell = [self.collectionView cellForItemAtIndexPath:ip];
190 | }
191 | - (void)didReceiveMemoryWarning {
192 | [super didReceiveMemoryWarning];
193 | // Dispose of any resources that can be recreated.
194 | }
195 | - (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
196 | {
197 | return self.assets.count;
198 | }
199 | -(void) showCamera
200 | {
201 | NSLog(@"Camera Selected");
202 | }
203 | - (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
204 | {
205 | static NSString *cellIdentifier = @"PhotoPickerCell";
206 | static NSString *cameraCellIdentifier = @"CameraCell";
207 |
208 | if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
209 | {
210 | if(indexPath.row == 0 && indexPath.section == 0 && showOnlyPhotosWithGPS == NO)
211 | {
212 | CameraCell *cell = (CameraCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cameraCellIdentifier forIndexPath:indexPath];
213 | ALAsset *asset = self.assets[indexPath.row];
214 | ALAssetRepresentation *rep = [asset defaultRepresentation];
215 | NSString *assetURL = [[rep url] absoluteString];
216 | cell.asset = asset;
217 | cell.backgroundColor = [UIColor whiteColor];
218 | if([highLightThese containsObject:assetURL])
219 | {
220 | cell.layer.borderColor = [[UIColor orangeColor] CGColor];
221 | cell.layer.borderWidth = 4.0;
222 | [cell setAlpha:1.0];
223 | [cell setUserInteractionEnabled:YES];
224 | }
225 | else
226 | {
227 | if([highLightThese count] == maxPhotos)
228 | {
229 | cell.layer.borderColor = nil;
230 | cell.layer.borderWidth = 0.0;
231 | [cell setAlpha:0.5];
232 | [cell setUserInteractionEnabled:NO];
233 | }
234 | else
235 | {
236 | cell.layer.borderColor = nil;
237 | cell.layer.borderWidth = 0.0;
238 | [cell setAlpha:1.0];
239 | [cell setUserInteractionEnabled:YES];
240 | }
241 | }
242 | return cell;
243 | }
244 | else
245 | {
246 | PhotoPickerCell *cell = (PhotoPickerCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
247 |
248 | ALAsset *asset = self.assets[indexPath.row];
249 | ALAssetRepresentation *rep = [asset defaultRepresentation];
250 | NSString *assetURL = [[rep url] absoluteString];
251 | cell.asset = asset;
252 | cell.backgroundColor = [UIColor whiteColor];
253 | if([highLightThese containsObject:assetURL])
254 | {
255 | cell.layer.borderColor = [[UIColor orangeColor] CGColor];
256 | cell.layer.borderWidth = 4.0;
257 | [cell setAlpha:1.0];
258 | [cell setUserInteractionEnabled:YES];
259 | }
260 | else
261 | {
262 | if([highLightThese count] == maxPhotos)
263 | {
264 | cell.layer.borderColor = nil;
265 | cell.layer.borderWidth = 0.0;
266 | [cell setAlpha:0.5];
267 | [cell setUserInteractionEnabled:NO];
268 | }
269 | else
270 | {
271 | cell.layer.borderColor = nil;
272 | cell.layer.borderWidth = 0.0;
273 | [cell setAlpha:1.0];
274 | [cell setUserInteractionEnabled:YES];
275 | }
276 | }
277 | return cell;
278 | }
279 | } // Device with Camera
280 | else
281 | {
282 | PhotoPickerCell *cell = (PhotoPickerCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
283 |
284 | ALAsset *asset = self.assets[indexPath.row];
285 | ALAssetRepresentation *rep = [asset defaultRepresentation];
286 | NSString *assetURL = [[rep url] absoluteString];
287 | cell.asset = asset;
288 | cell.backgroundColor = [UIColor whiteColor];
289 | if([highLightThese containsObject:assetURL])
290 | {
291 | cell.layer.borderColor = [[UIColor orangeColor] CGColor];
292 | cell.layer.borderWidth = 4.0;
293 | [cell setAlpha:1.0];
294 | [cell setUserInteractionEnabled:YES];
295 | }
296 | else
297 | {
298 | if([highLightThese count] == maxPhotos)
299 | {
300 | cell.layer.borderColor = nil;
301 | cell.layer.borderWidth = 0.0;
302 | [cell setAlpha:0.5];
303 | [cell setUserInteractionEnabled:NO];
304 | }
305 | else
306 | {
307 | cell.layer.borderColor = nil;
308 | cell.layer.borderWidth = 0.0;
309 | [cell setAlpha:1.0];
310 | [cell setUserInteractionEnabled:YES];
311 | }
312 | }
313 | return cell;
314 | } // Device Without Camera
315 | return Nil;
316 | }
317 |
318 | - (CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
319 | {
320 | return 4;
321 | }
322 |
323 | - (CGFloat) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
324 | {
325 | return 1;
326 | }
327 | /*
328 | #pragma mark - Navigation
329 |
330 | // In a storyboard-based application, you will often want to do a little preparation before navigation
331 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
332 | // Get the new view controller using [segue destinationViewController].
333 | // Pass the selected object to the new view controller.
334 | }
335 | */
336 |
337 | + (ALAssetsLibrary *)defaultAssetsLibrary
338 | {
339 | static dispatch_once_t pred = 0;
340 | static ALAssetsLibrary *library = nil;
341 | dispatch_once(&pred, ^{
342 | library = [[ALAssetsLibrary alloc] init];
343 | });
344 | return library;
345 | }
346 |
347 | -(void) collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
348 | {
349 | ALAsset *asset = self.assets[indexPath.row];
350 | ALAssetRepresentation *rep = [asset defaultRepresentation];
351 | NSString *assetURL = [[rep url] absoluteString];
352 |
353 | if([highLightThese containsObject:assetURL])
354 | {
355 | [highLightThese removeObject:assetURL];
356 | // if(![disselectedImages containsObject:indexPath])
357 | // [disselectedImages addObject:indexPath];
358 | // [collectionView reloadItemsAtIndexPaths:selectedImages];
359 | // [collectionView reloadItemsAtIndexPaths:disselectedImages];
360 | [collectionView reloadData];
361 | }
362 | }
363 |
364 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
365 |
366 | if(indexPath.row == 0 && indexPath.section == 0 && [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] && showOnlyPhotosWithGPS == NO)
367 | {
368 | if([self checkForCamera] == YES)
369 | {
370 | YCameraViewController *ycv = [[YCameraViewController alloc] init];
371 | [ycv setDelegate:self];
372 | [ycv setCurrentUserLocation:currentUserLocation];
373 | [self presentViewController:ycv animated:YES completion:^{
374 | }];
375 | }
376 | else
377 | {
378 | [self displayErrorOnMainQueue:@"Camera Access Disabled" message:@"Please allow Camera Access in System Settings"];
379 | }
380 |
381 | }
382 | else
383 | {
384 | ALAsset *asset = self.assets[indexPath.row];
385 | ALAssetRepresentation *rep = [asset defaultRepresentation];
386 | NSString *assetURL = [[rep url] absoluteString];
387 |
388 | if(![highLightThese containsObject:assetURL] && ([highLightThese count] < maxPhotos))
389 | {
390 | [highLightThese addObject:assetURL];
391 | }
392 | else
393 | {
394 | [highLightThese removeObject:assetURL];
395 | }
396 | if([highLightThese count]>=1)
397 | [nextButton setHidden:NO];
398 | else
399 | [nextButton setHidden:YES];
400 | [collectionView reloadData];
401 | }
402 | }
403 | -(IBAction)donePressed:(id)sender
404 | {
405 | if([highLightThese count] == 0)
406 | {
407 | NSLog(@"Please Select One");
408 | }
409 | else
410 | {
411 | NSMutableArray *allImagesIPicked = [[NSMutableArray alloc] init];
412 | for(NSString *ip in highLightThese)
413 | {
414 | [allImagesIPicked addObject:ip];
415 | } // end of for loop
416 | [self dismissViewControllerAnimated:NO completion:^{
417 | if ([self.delegate respondsToSelector:@selector(imageSelected:)]) {
418 | [self.delegate imageSelected:allImagesIPicked];
419 | }
420 | }];
421 |
422 | }
423 | }
424 | -(IBAction)skipPressed:(id)sender
425 | {
426 | // self.selectedImage = Nil;
427 | [self dismissViewControllerAnimated:NO completion:^{
428 | if ([self.delegate respondsToSelector:@selector(imageSelected:)]) {
429 | [self.delegate imageSelected:Nil];
430 | }
431 | }];
432 | }
433 | -(UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize sourceImage:(UIImage*)sourceImage
434 | {
435 | UIImage *newImage = nil;
436 | CGSize imageSize = sourceImage.size;
437 | CGFloat width = imageSize.width;
438 | CGFloat height = imageSize.height;
439 | CGFloat targetWidth = targetSize.width;
440 | CGFloat targetHeight = targetSize.height;
441 | CGFloat scaleFactor = 0.0;
442 | CGFloat scaledWidth = targetWidth;
443 | CGFloat scaledHeight = targetHeight;
444 | CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
445 |
446 | if (CGSizeEqualToSize(imageSize, targetSize) == NO)
447 | {
448 | CGFloat widthFactor = targetWidth / width;
449 | CGFloat heightFactor = targetHeight / height;
450 |
451 | if (widthFactor > heightFactor)
452 | {
453 | scaleFactor = widthFactor; // scale to fit height
454 | }
455 | else
456 | {
457 | scaleFactor = heightFactor; // scale to fit width
458 | }
459 |
460 | scaledWidth = width * scaleFactor;
461 | scaledHeight = height * scaleFactor;
462 |
463 | // center the image
464 | if (widthFactor > heightFactor)
465 | {
466 | thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
467 | }
468 | else
469 | {
470 | if (widthFactor < heightFactor)
471 | {
472 | thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
473 | }
474 | }
475 | }
476 |
477 | UIGraphicsBeginImageContext(targetSize); // this will crop
478 | //UIGraphicsBeginImageContextWithOptions(targetSize, 1.0, 0.0);
479 |
480 | CGRect thumbnailRect = CGRectZero;
481 | thumbnailRect.origin = thumbnailPoint;
482 | thumbnailRect.size.width = scaledWidth;
483 | thumbnailRect.size.height = scaledHeight;
484 |
485 | [sourceImage drawInRect:thumbnailRect];
486 |
487 | newImage = UIGraphicsGetImageFromCurrentImageContext();
488 |
489 | if(newImage == nil)
490 | {
491 | NSLog(@"could not scale image");
492 | }
493 |
494 | //pop the context to get back to the default
495 | UIGraphicsEndImageContext();
496 |
497 | return newImage;
498 | }
499 | //- (UIImage *)fixrotation:(UIImage *)image{
500 | //
501 | //
502 | // if (image.imageOrientation == UIImageOrientationUp) return image;
503 | // CGAffineTransform transform = CGAffineTransformIdentity;
504 | //
505 | // switch (image.imageOrientation) {
506 | // case UIImageOrientationDown:
507 | // case UIImageOrientationDownMirrored:
508 | // transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height);
509 | // transform = CGAffineTransformRotate(transform, M_PI);
510 | // break;
511 | //
512 | // case UIImageOrientationLeft:
513 | // case UIImageOrientationLeftMirrored:
514 | // transform = CGAffineTransformTranslate(transform, image.size.width, 0);
515 | // transform = CGAffineTransformRotate(transform, M_PI_2);
516 | // break;
517 | //
518 | // case UIImageOrientationRight:
519 | // case UIImageOrientationRightMirrored:
520 | // transform = CGAffineTransformTranslate(transform, 0, image.size.height);
521 | // transform = CGAffineTransformRotate(transform, -M_PI_2);
522 | // break;
523 | // case UIImageOrientationUp:
524 | // case UIImageOrientationUpMirrored:
525 | // break;
526 | // }
527 | //
528 | // switch (image.imageOrientation) {
529 | // case UIImageOrientationUpMirrored:
530 | // case UIImageOrientationDownMirrored:
531 | // transform = CGAffineTransformTranslate(transform, image.size.width, 0);
532 | // transform = CGAffineTransformScale(transform, -1, 1);
533 | // break;
534 | //
535 | // case UIImageOrientationLeftMirrored:
536 | // case UIImageOrientationRightMirrored:
537 | // transform = CGAffineTransformTranslate(transform, image.size.height, 0);
538 | // transform = CGAffineTransformScale(transform, -1, 1);
539 | // break;
540 | // case UIImageOrientationUp:
541 | // case UIImageOrientationDown:
542 | // case UIImageOrientationLeft:
543 | // case UIImageOrientationRight:
544 | // break;
545 | // }
546 | //
547 | // // Now we draw the underlying CGImage into a new context, applying the transform
548 | // // calculated above.
549 | // CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height,
550 | // CGImageGetBitsPerComponent(image.CGImage), 0,
551 | // CGImageGetColorSpace(image.CGImage),
552 | // CGImageGetBitmapInfo(image.CGImage));
553 | // CGContextConcatCTM(ctx, transform);
554 | // switch (image.imageOrientation) {
555 | // case UIImageOrientationLeft:
556 | // case UIImageOrientationLeftMirrored:
557 | // case UIImageOrientationRight:
558 | // case UIImageOrientationRightMirrored:
559 | // // Grr...
560 | // CGContextDrawImage(ctx, CGRectMake(0,0,image.size.height,image.size.width), image.CGImage);
561 | // break;
562 | //
563 | // default:
564 | // CGContextDrawImage(ctx, CGRectMake(0,0,image.size.width,image.size.height), image.CGImage);
565 | // break;
566 | // }
567 | //
568 | // // And now we just create a new UIImage from the drawing context
569 | // CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
570 | // UIImage *img = [UIImage imageWithCGImage:cgimg];
571 | // CGContextRelease(ctx);
572 | // CGImageRelease(cgimg);
573 | // return img;
574 | //
575 | //}
576 |
577 | -(IBAction)cancelPressed:(id)sender
578 | {
579 | // self.selectedImage = Nil;
580 | [self dismissViewControllerAnimated:NO completion:^{
581 | if ([self.delegate respondsToSelector:@selector(imageSelectionCancelled)]) {
582 | [self.delegate imageSelectionCancelled];
583 | }
584 | }];
585 |
586 | }
587 |
588 |
589 | - (void) initializeCamera {
590 | if (session)
591 | [session release], session=nil;
592 | CameraCell *firstCell = (CameraCell*)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
593 | UIImageView *view = [firstCell getImageView];
594 | session = [[AVCaptureSession alloc] init];
595 | session.sessionPreset = AVCaptureSessionPresetLow;
596 |
597 | if (captureVideoPreviewLayer)
598 | [captureVideoPreviewLayer release], captureVideoPreviewLayer=nil;
599 |
600 | captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
601 | [captureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
602 |
603 | captureVideoPreviewLayer.frame = view.bounds;
604 | [view.layer addSublayer:captureVideoPreviewLayer];
605 |
606 |
607 | CALayer *viewLayer = [view layer];
608 | [viewLayer setMasksToBounds:YES];
609 |
610 | CGRect bounds = [view bounds];
611 | [captureVideoPreviewLayer setFrame:bounds];
612 |
613 | NSArray *devices = [AVCaptureDevice devices];
614 | AVCaptureDevice *backCamera=nil;
615 |
616 | // check if device available
617 | if (devices.count==0) {
618 | NSLog(@"No Camera Available");
619 | return;
620 | }
621 |
622 | for (AVCaptureDevice *device in devices) {
623 |
624 | NSLog(@"Device name: %@", [device localizedName]);
625 |
626 | if ([device hasMediaType:AVMediaTypeVideo]) {
627 |
628 | if ([device position] == AVCaptureDevicePositionBack) {
629 | NSLog(@"Device position : back");
630 | backCamera = device;
631 | }
632 | }
633 | }
634 | NSError *error = nil;
635 | AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error];
636 | if (!input) {
637 | NSLog(@"ERROR: trying to open camera: %@", error);
638 | }
639 | else
640 | {
641 | [session addInput:input];
642 | if (stillImageOutput)
643 | [stillImageOutput release], stillImageOutput=nil;
644 |
645 | stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
646 | NSDictionary *outputSettings = [[[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil] autorelease];
647 | [stillImageOutput setOutputSettings:outputSettings];
648 |
649 | [session addOutput:stillImageOutput];
650 |
651 | [session startRunning];
652 | }
653 |
654 | }
655 |
656 |
657 | -(void) doSomeThingWithImage:(NSDictionary*)params
658 | {
659 | UIImage *image = [params objectForKey:@"data"];
660 | NSDictionary *metadata = [params objectForKey:@"metadata"];
661 | params = Nil;
662 | ALAssetsLibrary *assetsLibrary = [CustomeImagePicker defaultAssetsLibrary];
663 | [assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage
664 | metadata:metadata
665 | completionBlock:^(NSURL *assetURL, NSError *error) {
666 | [self dismissViewControllerAnimated:NO completion:^{
667 | NSMutableArray *allImagesIPicked = [[NSMutableArray alloc] init];
668 | [allImagesIPicked addObject:assetURL.absoluteString];
669 | // Now insert the Camera Image at 0 and 2 more
670 | if([highLightThese count]>=1)
671 | {
672 | int count = 1;
673 | for(NSString *ip in highLightThese)
674 | {
675 | [allImagesIPicked addObject:ip];
676 | count++;
677 | if(count >= maxPhotos)
678 | break;
679 | } // end of for loop
680 | }
681 | if ([self.delegate respondsToSelector:@selector(imageSelected:)]) {
682 | [self.delegate imageSelected:allImagesIPicked];
683 | }
684 | }];
685 |
686 |
687 |
688 | }];
689 | }
690 |
691 |
692 |
693 | /* YCameraView Delegate Start */
694 | -(void)didFinishPickingImage:(UIImage *)image metadata:(NSDictionary *)metadata {
695 | // Use image as per your need
696 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
697 | dispatch_async(dispatch_get_main_queue(), ^{
698 | [self.view showActivityView];
699 | });
700 |
701 |
702 | NSDictionary *extraParams = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:image,metadata,nil] forKeys:[NSArray arrayWithObjects:@"data",@"metadata",nil]];
703 |
704 | [NSThread detachNewThreadSelector:@selector(doSomeThingWithImage:) toTarget:self withObject:extraParams];
705 |
706 | });
707 |
708 | }
709 | /* YCameraView Delegate End */
710 |
711 |
712 | @end
713 |
--------------------------------------------------------------------------------
/CustomImagePicker/CustomeImagePicker.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
36 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/CustomImagePicker/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/CustomImagePicker/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | mompop.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | CustomeImagePicker
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UIStatusBarHidden
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/CustomImagePicker/OLGhostAlertView.h:
--------------------------------------------------------------------------------
1 | //
2 | // OLGhostAlertView.h
3 | //
4 | // Originally created by Radu Dutzan.
5 | // (c) 2012 Onda.
6 | //
7 |
8 | #import
9 |
10 | typedef NS_ENUM(NSUInteger, OLGhostAlertViewPosition) {
11 | OLGhostAlertViewPositionBottom,
12 | OLGhostAlertViewPositionCenter,
13 | OLGhostAlertViewPositionTop
14 | };
15 |
16 | typedef NS_ENUM(NSUInteger, OLGhostAlertViewStyle) {
17 | OLGhostAlertViewStyleDefault, // defaults to OLGhostAlertViewStyleDark
18 | OLGhostAlertViewStyleLight,
19 | OLGhostAlertViewStyleDark
20 | };
21 |
22 | @interface OLGhostAlertView : UIView
23 |
24 | /**
25 | Equivalent to `initWithTitle:message:timeout:dismissible:`, but assumes default values for `message` (nil) `timeout` (4 seconds) and `dismissible` (YES).
26 | @param title The string that appears in the view's title label.
27 | */
28 | - (id)initWithTitle:(NSString *)title;
29 |
30 | /**
31 | Equivalent to `initWithTitle:message:timeout:dismissible:`, but assumes default values for `timeout` (6 seconds) and `dismissible` (YES).
32 | @param title The string that appears in the view's title label.
33 | @param message Descriptive text that provides more details than the title. Can be nil.
34 | */
35 | - (id)initWithTitle:(NSString *)title message:(NSString *)message;
36 |
37 | /**
38 | Initializes a new OLGhostAlertView instance.
39 | @param title The string that appears in the view's title label.
40 | @param message Descriptive text that provides more details than the title. Can be nil.
41 | @param timeout Time interval before the alert is automatically dismissed.
42 | @param dismissible Whether the alert can be dismissed with a tap or not.
43 | */
44 | - (id)initWithTitle:(NSString *)title message:(NSString *)message timeout:(NSTimeInterval)timeout dismissible:(BOOL)dismissible;
45 |
46 | /**
47 | Shows the OLGhostAlertView on top of the frontmost view controller.
48 | */
49 | - (void)show;
50 |
51 | /**
52 | Shows the OLGhostAlertView on top of the given `view`.
53 | */
54 | - (void)showInView:(UIView *)view;
55 |
56 | /**
57 | Hides the OLGhostAlertView.
58 | */
59 | - (void)hide;
60 |
61 |
62 | /**
63 | The vertical position of the view.
64 |
65 | The default value is `OLGhostAlertViewPositionBottom`.
66 | */
67 | @property (nonatomic) OLGhostAlertViewPosition position;
68 |
69 | /**
70 | The visual style of the view.
71 |
72 | The view can have either light text on a dark background (`OLGhostAlertViewStyleDark`) or dark text over a light background (`OLGhostAlertViewStyleLight`).
73 |
74 | The default value is `OLGhostAlertViewStyleDefault`, which maps to `OLGhostAlertViewStyleLight`.
75 | */
76 | @property (nonatomic) OLGhostAlertViewStyle style;
77 |
78 | /**
79 | A margin that prevents the alert from drawing above it.
80 | */
81 | @property (nonatomic) CGFloat topContentMargin;
82 |
83 | /**
84 | A margin that prevents the alert from drawing below it.
85 | */
86 | @property (nonatomic) CGFloat bottomContentMargin;
87 |
88 | /**
89 | A block to execute after the instance has been dismissed.
90 | */
91 | @property (nonatomic, copy) void (^completionBlock)(void);
92 |
93 | /**
94 | The string that appears in the title of the alert.
95 | */
96 | @property (nonatomic) NSString *title;
97 |
98 | /**
99 | Descriptive text that provides more details than the title.
100 | */
101 | @property (nonatomic) NSString *message;
102 |
103 | /**
104 | The label that displays the title.
105 | */
106 | @property (nonatomic, strong) UILabel *titleLabel;
107 |
108 | /**
109 | The label that displays the message.
110 | */
111 | @property (nonatomic, strong) UILabel *messageLabel;
112 |
113 | /**
114 | Time interval before the alert is automatically dismissed.
115 | */
116 | @property (nonatomic) NSTimeInterval timeout;
117 |
118 | /**
119 | Whether the alert can be dismissed with a tap or not.
120 | */
121 | @property (nonatomic) BOOL dismissible;
122 |
123 | /**
124 | A Boolean value that indicates whether the view is currently visible on the screen.
125 | */
126 | @property (nonatomic, readonly, getter=isVisible) BOOL visible;
127 |
128 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/OLGhostAlertView.m:
--------------------------------------------------------------------------------
1 | //
2 | // OLGhostAlertView.m
3 | //
4 | // Originally created by Radu Dutzan.
5 | // (c) 2012-2013 Onda.
6 | //
7 |
8 | #import
9 | #import "OLGhostAlertView.h"
10 |
11 | #define HORIZONTAL_PADDING 18.0
12 | #define VERTICAL_PADDING 14.0
13 | #define TITLE_FONT_SIZE 17
14 | #define MESSAGE_FONT_SIZE 14
15 |
16 | @interface OLGhostAlertView ()
17 |
18 | @property (strong, nonatomic) UITapGestureRecognizer *dismissTap;
19 | @property UIInterfaceOrientation interfaceOrientation;
20 | @property CGFloat innerMargin;
21 | @property BOOL keyboardIsVisible;
22 | @property CGFloat keyboardHeight;
23 | @property (nonatomic, readwrite) BOOL visible;
24 |
25 | @end
26 |
27 | @implementation OLGhostAlertView
28 |
29 | #pragma mark - Initialization
30 |
31 | - (id)initWithFrame:(CGRect)frame
32 | {
33 | self = [super initWithFrame:frame];
34 | if (self) {
35 | self.layer.cornerRadius = 5.0f;
36 | self.backgroundColor = [UIColor colorWithWhite:0 alpha:.45];
37 | self.alpha = 0;
38 |
39 | self.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
40 | self.layer.shadowOffset = CGSizeMake(0, 0);
41 | self.layer.shadowOpacity = 1.0;
42 | self.layer.shadowRadius = 30.0;
43 |
44 | UIMotionEffectGroup *motionEffects = [UIMotionEffectGroup new];
45 |
46 | UIInterpolatingMotionEffect *horizontalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
47 | horizontalMotionEffect.minimumRelativeValue = @-14;
48 | horizontalMotionEffect.maximumRelativeValue = @14;
49 |
50 | UIInterpolatingMotionEffect *verticalMotionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
51 | verticalMotionEffect.minimumRelativeValue = @-18;
52 | verticalMotionEffect.maximumRelativeValue = @18;
53 |
54 | motionEffects.motionEffects = @[horizontalMotionEffect, verticalMotionEffect];
55 |
56 | [self addMotionEffect:motionEffects];
57 |
58 | _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(HORIZONTAL_PADDING, VERTICAL_PADDING, 0, 0)];
59 | _titleLabel.backgroundColor = [UIColor clearColor];
60 | _titleLabel.textColor = [UIColor whiteColor];
61 | _titleLabel.textAlignment = NSTextAlignmentCenter;
62 | _titleLabel.font = [UIFont boldSystemFontOfSize:TITLE_FONT_SIZE];
63 | _titleLabel.numberOfLines = 0;
64 | _titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
65 | _titleLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
66 |
67 | [self addSubview:_titleLabel];
68 |
69 | _messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(HORIZONTAL_PADDING, 0, 0, 0)];
70 | _messageLabel.backgroundColor = [UIColor clearColor];
71 | _messageLabel.textColor = [UIColor whiteColor];
72 | _messageLabel.textAlignment = NSTextAlignmentCenter;
73 | _messageLabel.font = [UIFont systemFontOfSize:MESSAGE_FONT_SIZE];
74 | _messageLabel.numberOfLines = 0;
75 | _messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
76 | _messageLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
77 |
78 | [self addSubview:_messageLabel];
79 |
80 | self.style = OLGhostAlertViewStyleDefault;
81 | _position = OLGhostAlertViewPositionBottom;
82 |
83 | _interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
84 |
85 | if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
86 | _innerMargin = 25;
87 | else
88 | _innerMargin = 50;
89 |
90 | _dismissTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)];
91 |
92 | [[NSNotificationCenter defaultCenter] addObserver:self
93 | selector:@selector(didChangeOrientation:)
94 | name:UIApplicationDidChangeStatusBarOrientationNotification
95 | object:nil];
96 |
97 | [[NSNotificationCenter defaultCenter] addObserver:self
98 | selector:@selector(keyboardWillShow:)
99 | name:UIKeyboardWillShowNotification
100 | object:nil];
101 |
102 | [[NSNotificationCenter defaultCenter] addObserver:self
103 | selector:@selector(keyboardWillHide:)
104 | name:UIKeyboardWillHideNotification
105 | object:nil];
106 | }
107 | return self;
108 | }
109 |
110 | - (id)initWithTitle:(NSString *)title message:(NSString *)message timeout:(NSTimeInterval)timeout dismissible:(BOOL)dismissible
111 | {
112 | self = [self initWithFrame:CGRectZero];
113 | if (self) {
114 | self.title = title;
115 | self.message = message;
116 | self.timeout = timeout;
117 | self.dismissible = dismissible;
118 | }
119 | return self;
120 | }
121 |
122 | - (id)initWithTitle:(NSString *)title message:(NSString *)message
123 | {
124 | self = [self initWithTitle:title message:message timeout:6 dismissible:YES];
125 | return self;
126 | }
127 |
128 | - (id)initWithTitle:(NSString *)title
129 | {
130 | self = [self initWithTitle:title message:nil timeout:4 dismissible:YES];
131 | return self;
132 | }
133 |
134 | #pragma mark - Show and hide
135 |
136 | - (void)show
137 | {
138 | if (!self.title && !self.message)
139 | NSLog(@"OLGhostAlertView: Your alert doesn't have any content.");
140 |
141 | if (self.isVisible) return;
142 |
143 | UIViewController *parentController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
144 |
145 | while (parentController.presentedViewController)
146 | parentController = parentController.presentedViewController;
147 |
148 | UIView *parentView = parentController.view;
149 |
150 | [self showInView:parentView];
151 | }
152 |
153 | - (void)showInView:(UIView *)view
154 | {
155 | for (UIView *subview in [view subviews]) {
156 | if ([subview isKindOfClass:[OLGhostAlertView class]]) {
157 | OLGhostAlertView *otherOLGAV = (OLGhostAlertView *)subview;
158 | [otherOLGAV hide];
159 | }
160 | }
161 |
162 | [view addSubview:self];
163 |
164 | self.visible = YES;
165 |
166 | [UIView animateWithDuration:0.5 animations:^{
167 | self.alpha = 1;
168 | } completion:^(BOOL finished) {
169 | [self performSelector:@selector(hide) withObject:nil afterDelay:self.timeout];
170 | }];
171 | }
172 |
173 | - (void)hide
174 | {
175 | [NSObject cancelPreviousPerformRequestsWithTarget:self];
176 |
177 | [UIView animateWithDuration:0.5 animations:^{
178 | self.alpha = 0;
179 | } completion:^(BOOL finished){
180 | self.visible = NO;
181 |
182 | [self removeFromSuperview];
183 |
184 | if (self.completionBlock) self.completionBlock();
185 | }];
186 | }
187 |
188 | #pragma mark - View layout
189 |
190 | - (void)layoutSubviews
191 | {
192 | CGFloat maxWidth = 0;
193 | CGFloat totalLabelWidth = 0;
194 | CGFloat totalHeight = 0;
195 |
196 | CGRect screenRect = self.superview.bounds;
197 |
198 | if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
199 | maxWidth = self.superview.bounds.size.width - 40.0 - (HORIZONTAL_PADDING * 2);
200 | } else {
201 | maxWidth = 520 - (HORIZONTAL_PADDING * 2);
202 | }
203 |
204 | CGSize constrainedSize = CGSizeZero;
205 | constrainedSize.width = maxWidth;
206 | constrainedSize.height = MAXFLOAT;
207 |
208 | CGSize titleSize = [self.title boundingRectWithSize:constrainedSize
209 | options:NSStringDrawingUsesLineFragmentOrigin
210 | attributes:@{NSFontAttributeName: self.titleLabel.font}
211 | context:nil].size;
212 | CGSize messageSize = CGSizeZero;
213 |
214 | if (self.message) {
215 | messageSize = [self.message boundingRectWithSize:constrainedSize
216 | options:NSStringDrawingUsesLineFragmentOrigin
217 | attributes:@{NSFontAttributeName: self.messageLabel.font}
218 | context:nil].size;
219 |
220 | totalHeight = titleSize.height + messageSize.height + floorf(VERTICAL_PADDING * 2.5);
221 |
222 | } else {
223 | totalHeight = titleSize.height + floorf(VERTICAL_PADDING * 2);
224 | }
225 |
226 | if (titleSize.width == maxWidth || messageSize.width == maxWidth) {
227 | totalLabelWidth = maxWidth;
228 |
229 | } else if (messageSize.width > titleSize.width) {
230 | totalLabelWidth = messageSize.width;
231 |
232 | } else {
233 | totalLabelWidth = titleSize.width;
234 | }
235 |
236 | CGFloat totalWidth = totalLabelWidth + (HORIZONTAL_PADDING * 2);
237 |
238 | CGFloat xPosition = floorf((screenRect.size.width / 2) - (totalWidth / 2));
239 |
240 | CGFloat yPosition = 0;
241 |
242 | switch (self.position) {
243 | case OLGhostAlertViewPositionBottom:
244 | default:
245 | yPosition = screenRect.size.height - ceilf(totalHeight) - self.innerMargin - self.bottomContentMargin;
246 | break;
247 |
248 | case OLGhostAlertViewPositionCenter:
249 | yPosition = ceilf((screenRect.size.height / 2) - (totalHeight / 2));
250 | break;
251 |
252 | case OLGhostAlertViewPositionTop:
253 | yPosition = self.innerMargin + self.topContentMargin;
254 | break;
255 | }
256 |
257 | self.frame = CGRectMake(xPosition, yPosition, ceilf(totalWidth), ceilf(totalHeight));
258 |
259 | if (self.keyboardIsVisible && self.position == OLGhostAlertViewPositionBottom) {
260 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y - self.keyboardHeight, self.frame.size.width, self.frame.size.height);
261 | }
262 |
263 | self.titleLabel.frame = CGRectMake(self.titleLabel.frame.origin.x, ceilf(self.titleLabel.frame.origin.y), ceilf(totalLabelWidth), ceilf(titleSize.height));
264 |
265 | if (self.messageLabel) {
266 | self.messageLabel.frame = CGRectMake(self.messageLabel.frame.origin.x, ceilf(titleSize.height) + floorf(VERTICAL_PADDING * 1.5), ceilf(totalLabelWidth), ceilf(messageSize.height));
267 | }
268 | }
269 |
270 | - (void)keyboardWillShow:(NSNotification*)notification
271 | {
272 | NSDictionary *keyboardInfo = [notification userInfo];
273 | CGSize keyboardSize = [[keyboardInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
274 |
275 | self.keyboardIsVisible = YES;
276 | self.keyboardHeight = keyboardSize.height;
277 |
278 | [self setNeedsLayout];
279 | }
280 |
281 | - (void)keyboardWillHide:(NSNotification*)notification
282 | {
283 | self.keyboardIsVisible = NO;
284 |
285 | [self setNeedsLayout];
286 | }
287 |
288 | #pragma mark - Orientation handling
289 |
290 | - (void)didChangeOrientation:(NSNotification *)notification
291 | {
292 | self.interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;
293 |
294 | [self setNeedsLayout];
295 | }
296 |
297 | #pragma mark - Setters
298 |
299 | - (void)setTitle:(NSString *)title
300 | {
301 | _title = title;
302 |
303 | self.titleLabel.text = title;
304 |
305 | [self setNeedsLayout];
306 | }
307 |
308 | - (void)setMessage:(NSString *)message
309 | {
310 | _message = message;
311 |
312 | self.messageLabel.text = message;
313 |
314 | [self setNeedsLayout];
315 | }
316 |
317 | - (void)setDismissible:(BOOL)dismissible
318 | {
319 | _dismissible = dismissible;
320 |
321 | if (dismissible) {
322 | [self addGestureRecognizer:self.dismissTap];
323 | } else {
324 | if (self.gestureRecognizers) [self removeGestureRecognizer:self.dismissTap];
325 | }
326 | }
327 |
328 | - (void)setStyle:(OLGhostAlertViewStyle)style
329 | {
330 | if (style == OLGhostAlertViewStyleDefault) style = OLGhostAlertViewStyleLight;
331 |
332 | _style = style;
333 |
334 | UIColor *backgroundColor = nil;
335 | UIColor *textColor = nil;
336 |
337 | if (style == OLGhostAlertViewStyleLight) {
338 | backgroundColor = [UIColor colorWithWhite:1 alpha:0.95];
339 | textColor = [UIColor blackColor];
340 | } else {
341 | backgroundColor = [UIColor colorWithWhite:0 alpha:.75];
342 | textColor = [UIColor whiteColor];
343 | }
344 |
345 | self.backgroundColor = backgroundColor;
346 | self.titleLabel.textColor = textColor;
347 | self.messageLabel.textColor = textColor;
348 | }
349 |
350 | - (void)setTopContentMargin:(CGFloat)topContentMargin
351 | {
352 | _topContentMargin = topContentMargin;
353 | [self setNeedsLayout];
354 | }
355 |
356 | - (void)setBottomContentMargin:(CGFloat)bottomContentMargin
357 | {
358 | _bottomContentMargin = bottomContentMargin;
359 | [self setNeedsLayout];
360 | }
361 |
362 | #pragma mark - Cleanup
363 |
364 | - (void)dealloc
365 | {
366 | [[NSNotificationCenter defaultCenter] removeObserver:self];
367 |
368 | [self removeGestureRecognizer:self.dismissTap];
369 | }
370 |
371 | @end
372 |
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.h
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface PhotoCell : UICollectionViewCell
13 | - (void) setAsset:(ALAsset *)asset;
14 | -(void) performSelectionAnimations;
15 | -(void) hideTick;
16 | -(void) showTick;
17 | @property(nonatomic, strong) ALAsset *asset;
18 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.m
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import "PhotoCell.h"
10 |
11 | @interface PhotoCell ()
12 | // 1
13 | @property(nonatomic, weak) IBOutlet UIImageView *photoImageView;
14 | @property(nonatomic, weak) IBOutlet UIImageView *tickView;
15 |
16 | @end
17 |
18 | @implementation PhotoCell
19 |
20 | - (id)initWithFrame:(CGRect)frame {
21 |
22 | self = [super initWithFrame:frame];
23 |
24 | if (self) {
25 | // Initialization code
26 | NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"PhotoCell" owner:self options:nil];
27 |
28 | if ([arrayOfViews count] < 1) {
29 | return nil;
30 | }
31 |
32 | if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
33 | return nil;
34 | }
35 |
36 | self = [arrayOfViews objectAtIndex:0];
37 |
38 | }
39 |
40 | return self;
41 |
42 | }
43 |
44 | -(void) showTick
45 | {
46 | [self.tickView setHidden:NO];
47 | }
48 | -(void) hideTick
49 | {
50 | [self.tickView setHidden:YES];
51 | }
52 | - (void) setAsset:(ALAsset *)asset
53 | {
54 | // 2
55 | _asset = asset;
56 | self.photoImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
57 | }
58 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoPickerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.h
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "Header.h"
12 |
13 | @interface PhotoPickerCell : UICollectionViewCell
14 | - (void) setAsset:(ALAsset *)asset;
15 | - (void) setImage:(UIImage *)image;
16 | - (UIImageView*) getImageView;
17 | -(void) performSelectionAnimations;
18 | -(void) hideTick;
19 | -(void) showTick;
20 | @property(nonatomic, strong) ALAsset *asset;
21 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoPickerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoCell.m
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import "PhotoPickerCell.h"
10 |
11 | @interface PhotoPickerCell ()
12 | // 1
13 | @property(nonatomic, weak) IBOutlet UIImageView *photoImageView;
14 | @property(nonatomic, weak) IBOutlet UIImageView *tickView;
15 |
16 | @end
17 |
18 | @implementation PhotoPickerCell
19 | - (UIImageView*) getImageView;
20 | {
21 | return self.photoImageView;
22 | }
23 | - (id)initWithFrame:(CGRect)frame {
24 |
25 | self = [super initWithFrame:frame];
26 |
27 | if (self) {
28 | // Initialization code
29 | NSArray *arrayOfViews = Nil;
30 | if(IS_IPHONE_6||IS_IPHONE_6P)
31 | arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"PhotoPickerCell" owner:self options:nil];
32 | else
33 | arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"PhotoPickerCell_5" owner:self options:nil];
34 |
35 |
36 | if ([arrayOfViews count] < 1) {
37 | return nil;
38 | }
39 |
40 | if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
41 | return nil;
42 | }
43 |
44 | self = [arrayOfViews objectAtIndex:0];
45 |
46 | }
47 |
48 | return self;
49 |
50 | }
51 |
52 | -(void) showTick
53 | {
54 | [self.tickView setHidden:NO];
55 | }
56 | -(void) hideTick
57 | {
58 | [self.tickView setHidden:YES];
59 | }
60 | - (void) setAsset:(ALAsset *)asset
61 | {
62 | // 2
63 | _asset = asset;
64 | self.photoImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
65 | }
66 | - (void) setImage:(UIImage *)image
67 | {
68 | [self.photoImageView setImage:image];
69 | }
70 | @end
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoPickerCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CustomImagePicker/PhotoPickerCell_5.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CustomImagePicker/RNActivityView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RNActivityView.h
3 | // Created by Romilson Nunes
4 | //
5 |
6 | #import
7 | #import
8 | #import
9 |
10 | @protocol RNActivityViewDelegate;
11 |
12 |
13 | typedef enum {
14 | /** Progress is shown using an UIActivityIndicatorView. This is the default. */
15 | RNActivityViewModeIndeterminate,
16 | /** Progress is shown using a round, pie-chart like, progress view. */
17 | RNActivityViewModeDeterminate,
18 | /** Progress is shown using a horizontal progress bar */
19 | RNActivityViewModeDeterminateHorizontalBar,
20 | /** Progress is shown using a ring-shaped progress view. */
21 | RNActivityViewModeAnnularDeterminate,
22 | /** Shows a custom view */
23 | RNActivityViewModeCustomView,
24 | /** Shows only labels */
25 | RNActivityViewModeText
26 | } RNActivityViewMode;
27 |
28 | typedef enum {
29 | /** Opacity animation */
30 | RNActivityViewAnimationFade,
31 | /** Opacity + scale animation */
32 | RNActivityViewAnimationZoom,
33 | RNActivityViewAnimationZoomOut = RNActivityViewAnimationZoom,
34 | RNActivityViewAnimationZoomIn
35 | } RNActivityViewAnimation;
36 |
37 |
38 | #ifndef rn_instancetype
39 | #if __has_feature(objc_instancetype)
40 | #define rn_instancetype instancetype
41 | #else
42 | #define rn_instancetype id
43 | #endif
44 | #endif
45 |
46 | typedef void (^RNActivityViewCompletionBlock)();
47 |
48 | @interface RNActivityView : UIView
49 |
50 | + (rn_instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
51 |
52 | + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
53 |
54 | + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated;
55 |
56 | + (rn_instancetype)HUDForView:(UIView *)view;
57 |
58 | + (NSArray *)allHUDsForView:(UIView *)view;
59 |
60 | - (id)initWithWindow:(UIWindow *)window;
61 | - (id)initWithView:(UIView *)view;
62 |
63 | - (void)show:(BOOL)animated;
64 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;
65 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block;
66 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(RNActivityViewCompletionBlock)completion;
67 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue;
68 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
69 | completionBlock:(RNActivityViewCompletionBlock)completion;
70 |
71 | - (void)hide:(BOOL)animated;
72 | - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay;
73 |
74 | - (void) setupDefaultValues;
75 |
76 | @property (copy) RNActivityViewCompletionBlock completionBlock;
77 | @property (assign) RNActivityViewMode mode; // default is RNActivityViewModeIndeterminate.
78 | @property (assign) RNActivityViewAnimation animationType;
79 | @property (strong) UIView *customView;
80 | @property (weak) id delegate;
81 | @property (copy) NSString *labelText; // then no message is displayed.
82 | @property (copy) NSString *detailsLabelText;
83 | @property (assign) float opacity; // Defaults to 0.8 (80% opacity)
84 | @property (strong) UIColor *color;
85 |
86 | /**
87 | * The x-axis offset of the HUD relative to the centre of the superview.
88 | */
89 | @property (assign) float xOffset;
90 |
91 | /**
92 | * The y-axis offset of the HUD relative to the centre of the superview.
93 | */
94 | @property (assign) float yOffset;
95 |
96 | @property (assign) float margin; // Defaults to 20.0
97 | @property (assign) float cornerRadius; // Defaults to 10.0
98 | @property (assign) BOOL dimBackground; // Cover the HUD background view with a radial gradient
99 |
100 | /*
101 | * Grace period is the time (in seconds) that the invoked method may be run without
102 | * showing the HUD. If the task finishes before the grace time runs out, the HUD will
103 | * not be shown at all.
104 | * This may be used to prevent HUD display for very short tasks.
105 | * Defaults to 0 (no grace time).
106 | * Grace time functionality is only supported when the task status is known!
107 | * @see taskInProgress
108 | */
109 | @property (assign) float graceTime;
110 |
111 | // The minimum time (in seconds) that the HUD is shown.
112 | // Defaults 0 (no minimum show time).
113 | @property (assign) float minShowTime;
114 |
115 | @property (assign) BOOL taskInProgress;
116 |
117 | @property (assign) BOOL removeFromSuperViewOnHide; // Defaults NO
118 |
119 | @property (strong) UIFont* labelFont;
120 | @property (strong) UIColor* labelColor;
121 | @property (strong) UIFont* detailsLabelFont;
122 | @property (strong) UIColor* detailsLabelColor;
123 |
124 | @property (assign) float progress; // 0.0 to 1.0
125 | @property (assign) CGSize minSize; // Defaults to CGSizeZero (no minimum size)
126 | @property (assign, getter = isSquare) BOOL square;
127 |
128 | @end
129 |
130 | /*
131 | Protocol
132 | */
133 | @protocol RNActivityViewDelegate
134 | @optional
135 | - (void)hudWasHidden:(RNActivityView *)hud;
136 | @end
137 |
138 |
139 | /**
140 | * A progress view for showing definite progress by filling up a circle (pie chart).
141 | */
142 | @interface RNRoundProgressView : UIView
143 |
144 | @property (nonatomic, assign) float progress; // Progress (0.0 to 1.0)
145 | @property (nonatomic, strong) UIColor *progressTintColor; // Defaults White
146 | @property (nonatomic, strong) UIColor *backgroundTintColor; // Defaults to translucent white (alpha 0.1)
147 | @property (nonatomic, assign, getter = isAnnular) BOOL annular; // Display mode - NO = round or YES = annular. Defaults to round.
148 |
149 | @end
150 |
151 |
152 | /**
153 | * A flat bar progress view.
154 | */
155 | @interface RNBarProgressView : UIView
156 |
157 | @property (nonatomic, assign) float progress; // Progress (0.0 to 1.0)
158 | @property (nonatomic, strong) UIColor *lineColor; // Defaults to white
159 | @property (nonatomic, strong) UIColor *progressRemainingColor; // Defaults to clear
160 | @property (nonatomic, strong) UIColor *progressColor; // Defaults to white
161 |
162 | @end
163 |
--------------------------------------------------------------------------------
/CustomImagePicker/RNActivityView.m:
--------------------------------------------------------------------------------
1 | //
2 | // RNActivityView.m
3 | // Created by Romilson Nunes
4 | //
5 |
6 | #import "RNActivityView.h"
7 | #import
8 |
9 |
10 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
11 | #define RNLabelAlignmentCenter NSTextAlignmentCenter
12 | #else
13 | #define RNLabelAlignmentCenter UITextAlignmentCenter
14 | #endif
15 |
16 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
17 | #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text \
18 | sizeWithAttributes:@{NSFontAttributeName:font}] : CGSizeZero;
19 | #else
20 | #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text sizeWithFont:font] : CGSizeZero;
21 | #endif
22 |
23 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
24 | #define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \
25 | boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin) \
26 | attributes:@{NSFontAttributeName:font} context:nil].size : CGSizeZero;
27 | #else
28 | #define MB_MULTILINE_TEXTSIZE(text, font, maxSize, mode) [text length] > 0 ? [text \
29 | sizeWithFont:font constrainedToSize:maxSize lineBreakMode:mode] : CGSizeZero;
30 | #endif
31 |
32 |
33 | static const CGFloat kPadding = 4.f;
34 | static const CGFloat kLabelFontSize = 16.f;
35 | static const CGFloat kDetailsLabelFontSize = 12.f;
36 |
37 |
38 | @interface RNActivityView ()
39 |
40 | - (void)setupLabels;
41 | - (void)registerForKVO;
42 | - (void)unregisterFromKVO;
43 | - (NSArray *)observableKeypaths;
44 | - (void)registerForNotifications;
45 | - (void)unregisterFromNotifications;
46 | - (void)updateUIForKeypath:(NSString *)keyPath;
47 | - (void)hideUsingAnimation:(BOOL)animated;
48 | - (void)showUsingAnimation:(BOOL)animated;
49 | - (void)done;
50 | - (void)updateIndicators;
51 | - (void)handleGraceTimer:(NSTimer *)theTimer;
52 | - (void)handleMinShowTimer:(NSTimer *)theTimer;
53 | - (void)setTransformForCurrentOrientation:(BOOL)animated;
54 | - (void)cleanUp;
55 | - (void)launchExecution;
56 | - (void)deviceOrientationDidChange:(NSNotification *)notification;
57 | - (void)hideDelayed:(NSNumber *)animated;
58 |
59 | @property (atomic, strong) UIView *indicator;
60 | @property (atomic, strong) NSTimer *graceTimer;
61 | @property (atomic, strong) NSTimer *minShowTimer;
62 | @property (atomic, strong) NSDate *showStarted;
63 | @property (atomic, assign) CGSize size;
64 |
65 | @end
66 |
67 |
68 | @implementation RNActivityView {
69 | BOOL useAnimation;
70 | SEL methodForExecution;
71 | id targetForExecution;
72 | id objectForExecution;
73 | UILabel *label;
74 | UILabel *detailsLabel;
75 | BOOL isFinished;
76 | CGAffineTransform rotationTransform;
77 | }
78 |
79 | #pragma mark - Properties
80 |
81 | @synthesize animationType;
82 | @synthesize delegate;
83 | @synthesize opacity;
84 | @synthesize color;
85 | @synthesize labelFont;
86 | @synthesize labelColor;
87 | @synthesize detailsLabelFont;
88 | @synthesize detailsLabelColor;
89 | @synthesize indicator;
90 | @synthesize xOffset;
91 | @synthesize yOffset;
92 | @synthesize minSize;
93 | @synthesize square;
94 | @synthesize margin;
95 | @synthesize dimBackground;
96 | @synthesize graceTime;
97 | @synthesize minShowTime;
98 | @synthesize graceTimer;
99 | @synthesize minShowTimer;
100 | @synthesize taskInProgress;
101 | @synthesize removeFromSuperViewOnHide;
102 | @synthesize customView;
103 | @synthesize showStarted;
104 | @synthesize mode;
105 | @synthesize labelText;
106 | @synthesize detailsLabelText;
107 | @synthesize progress;
108 | @synthesize size;
109 | @synthesize completionBlock;
110 |
111 | #pragma mark - Class methods
112 |
113 | + (rn_instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated {
114 | RNActivityView *hud = [[self alloc] initWithView:view];
115 | [view addSubview:hud];
116 | [hud show:animated];
117 | return hud;
118 | }
119 |
120 | + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated {
121 | RNActivityView *hud = [self HUDForView:view];
122 | if (hud != nil) {
123 | hud.removeFromSuperViewOnHide = YES;
124 | [hud hide:animated];
125 | return YES;
126 | }
127 | return NO;
128 | }
129 |
130 | + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated {
131 | NSArray *huds = [RNActivityView allHUDsForView:view];
132 | for (RNActivityView *hud in huds) {
133 | hud.removeFromSuperViewOnHide = YES;
134 | [hud hide:animated];
135 | }
136 | return [huds count];
137 | }
138 |
139 | + (rn_instancetype)HUDForView:(UIView *)view {
140 | NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];
141 | for (UIView *subview in subviewsEnum) {
142 | if ([subview isKindOfClass:self]) {
143 | return (RNActivityView *)subview;
144 | }
145 | }
146 | return nil;
147 | }
148 |
149 | + (NSArray *)allHUDsForView:(UIView *)view {
150 | NSMutableArray *huds = [NSMutableArray array];
151 | NSArray *subviews = view.subviews;
152 | for (UIView *aView in subviews) {
153 | if ([aView isKindOfClass:self]) {
154 | [huds addObject:aView];
155 | }
156 | }
157 | return [NSArray arrayWithArray:huds];
158 | }
159 |
160 | #pragma mark - Setup
161 |
162 | - (void) setupDefaultValues {
163 | // Set default values for properties
164 | self.animationType = RNActivityViewAnimationFade;
165 | self.mode = RNActivityViewModeIndeterminate;
166 | self.labelText = nil;
167 | self.detailsLabelText = nil;
168 | self.opacity = 0.8f;
169 | self.color = nil;
170 | self.labelFont = [UIFont boldSystemFontOfSize:kLabelFontSize];
171 | self.labelColor = [UIColor whiteColor];
172 | self.detailsLabelFont = [UIFont boldSystemFontOfSize:kDetailsLabelFontSize];
173 | self.detailsLabelColor = [UIColor whiteColor];
174 | self.xOffset = 0.0f;
175 | self.yOffset = 0.0f;
176 | self.dimBackground = NO;
177 | self.margin = 20.0f;
178 | self.cornerRadius = 10.0f;
179 | self.graceTime = 0.0f;
180 | self.minShowTime = 0.0f;
181 | self.removeFromSuperViewOnHide = NO;
182 | self.minSize = CGSizeZero;
183 | self.square = NO;
184 |
185 |
186 | // Transparent background
187 | self.opaque = NO;
188 | self.backgroundColor = [UIColor clearColor];
189 | // Make it invisible for now
190 | self.alpha = 0.0f;
191 |
192 | taskInProgress = NO;
193 | rotationTransform = CGAffineTransformIdentity;
194 |
195 | methodForExecution = nil;
196 | targetForExecution = nil;
197 | objectForExecution = nil;
198 | }
199 |
200 | #pragma mark - Lifecycle
201 |
202 | - (id)initWithFrame:(CGRect)frame {
203 | self = [super initWithFrame:frame];
204 | if (self) {
205 | // Set default values for properties
206 | [self setupDefaultValues];
207 | self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin
208 | | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
209 |
210 | [self setupLabels];
211 | [self updateIndicators];
212 | [self registerForKVO];
213 | [self registerForNotifications];
214 | }
215 | return self;
216 | }
217 |
218 | - (id)initWithView:(UIView *)view {
219 | NSAssert(view, @"View must not be nil.");
220 | return [self initWithFrame:view.bounds];
221 | }
222 |
223 | - (id)initWithWindow:(UIWindow *)window {
224 | return [self initWithView:window];
225 | }
226 |
227 | - (void)dealloc {
228 | [self unregisterFromNotifications];
229 | [self unregisterFromKVO];
230 | }
231 |
232 | #pragma mark - Show & hide
233 |
234 | - (void)show:(BOOL)animated {
235 | useAnimation = animated;
236 | // If the grace time is set postpone the HUD display
237 | if (self.graceTime > 0.0) {
238 | self.graceTimer = [NSTimer scheduledTimerWithTimeInterval:self.graceTime target:self
239 | selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO];
240 | }
241 | // ... otherwise show the HUD imediately
242 | else {
243 | [self setNeedsDisplay];
244 | [self showUsingAnimation:useAnimation];
245 | }
246 | }
247 |
248 | - (void)hide:(BOOL)animated {
249 | useAnimation = animated;
250 | // If the minShow time is set, calculate how long the hud was shown,
251 | // and pospone the hiding operation if necessary
252 | if (self.minShowTime > 0.0 && showStarted) {
253 | NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:showStarted];
254 | if (interv < self.minShowTime) {
255 | self.minShowTimer = [NSTimer scheduledTimerWithTimeInterval:(self.minShowTime - interv) target:self
256 | selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO];
257 | return;
258 | }
259 | }
260 | // ... otherwise hide the HUD immediately
261 | [self hideUsingAnimation:useAnimation];
262 | }
263 |
264 | - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay {
265 | [self performSelector:@selector(hideDelayed:) withObject:[NSNumber numberWithBool:animated] afterDelay:delay];
266 | }
267 |
268 | - (void)hideDelayed:(NSNumber *)animated {
269 | [self hide:[animated boolValue]];
270 | }
271 |
272 | #pragma mark - Timer callbacks
273 |
274 | - (void)handleGraceTimer:(NSTimer *)theTimer {
275 | // Show the HUD only if the task is still running
276 | if (taskInProgress) {
277 | [self setNeedsDisplay];
278 | [self showUsingAnimation:useAnimation];
279 | }
280 | }
281 |
282 | - (void)handleMinShowTimer:(NSTimer *)theTimer {
283 | [self hideUsingAnimation:useAnimation];
284 | }
285 |
286 | #pragma mark - View Hierrarchy
287 |
288 | - (void)didMoveToSuperview {
289 | // We need to take care of rotation ourselfs if we're adding the HUD to a window
290 | if ([self.superview isKindOfClass:[UIWindow class]]) {
291 | [self setTransformForCurrentOrientation:NO];
292 | }
293 | }
294 |
295 | #pragma mark - Internal show & hide operations
296 |
297 | - (void)showUsingAnimation:(BOOL)animated {
298 | if (animated && animationType == RNActivityViewAnimationZoomIn) {
299 | self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));
300 | } else if (animated && animationType == RNActivityViewAnimationZoomOut) {
301 | self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));
302 | }
303 | self.showStarted = [NSDate date];
304 | // Fade in
305 | if (animated) {
306 | [UIView beginAnimations:nil context:NULL];
307 | [UIView setAnimationDuration:0.30];
308 | self.alpha = 1.0f;
309 | if (animationType == RNActivityViewAnimationZoomIn || animationType == RNActivityViewAnimationZoomOut) {
310 | self.transform = rotationTransform;
311 | }
312 | [UIView commitAnimations];
313 | }
314 | else {
315 | self.alpha = 1.0f;
316 | }
317 | }
318 |
319 | - (void)hideUsingAnimation:(BOOL)animated {
320 | // Fade out
321 | if (animated && showStarted) {
322 | [UIView beginAnimations:nil context:NULL];
323 | [UIView setAnimationDuration:0.30];
324 | [UIView setAnimationDelegate:self];
325 | [UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
326 | // 0.02 prevents the hud from passing through touches during the animation the hud will get completely hidden
327 | // in the done method
328 | if (animationType == RNActivityViewAnimationZoomIn) {
329 | self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(1.5f, 1.5f));
330 | } else if (animationType == RNActivityViewAnimationZoomOut) {
331 | self.transform = CGAffineTransformConcat(rotationTransform, CGAffineTransformMakeScale(0.5f, 0.5f));
332 | }
333 |
334 | self.alpha = 0.02f;
335 | [UIView commitAnimations];
336 | }
337 | else {
338 | self.alpha = 0.0f;
339 | [self done];
340 | }
341 | self.showStarted = nil;
342 | }
343 |
344 | - (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void*)context {
345 | [self done];
346 | }
347 |
348 | - (void)done {
349 | [NSObject cancelPreviousPerformRequestsWithTarget:self];
350 | isFinished = YES;
351 | self.alpha = 0.0f;
352 | if (removeFromSuperViewOnHide) {
353 | [self removeFromSuperview];
354 | }
355 | if (self.completionBlock) {
356 | self.completionBlock();
357 | self.completionBlock = NULL;
358 | }
359 | if ([delegate respondsToSelector:@selector(hudWasHidden:)]) {
360 | [delegate performSelector:@selector(hudWasHidden:) withObject:self];
361 | }
362 | }
363 |
364 | #pragma mark - Threading
365 |
366 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated {
367 | methodForExecution = method;
368 | targetForExecution = target;
369 | objectForExecution = object;
370 | // Launch execution in new thread
371 | self.taskInProgress = YES;
372 | [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil];
373 | // Show HUD view
374 | [self show:animated];
375 | }
376 |
377 |
378 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block {
379 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
380 | [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
381 | }
382 |
383 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion {
384 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
385 | [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion];
386 | }
387 |
388 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue {
389 | [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL];
390 | }
391 |
392 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
393 | completionBlock:(RNActivityViewCompletionBlock)completion {
394 | self.taskInProgress = YES;
395 | self.completionBlock = completion;
396 | dispatch_async(queue, ^(void) {
397 | block();
398 | dispatch_async(dispatch_get_main_queue(), ^(void) {
399 | [self cleanUp];
400 | });
401 | });
402 | [self show:animated];
403 | }
404 |
405 |
406 | - (void)launchExecution {
407 | @autoreleasepool {
408 | #pragma clang diagnostic push
409 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
410 | // Start executing the requested task
411 | [targetForExecution performSelector:methodForExecution withObject:objectForExecution];
412 | #pragma clang diagnostic pop
413 | // Task completed, update view in main thread (note: view operations should
414 | // be done only in the main thread)
415 | [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];
416 | }
417 | }
418 |
419 | - (void)cleanUp {
420 | taskInProgress = NO;
421 | targetForExecution = nil;
422 | objectForExecution = nil;
423 | [self hide:useAnimation];
424 | }
425 |
426 | #pragma mark - UI
427 |
428 | - (void)setupLabels {
429 | label = [[UILabel alloc] initWithFrame:self.bounds];
430 | label.adjustsFontSizeToFitWidth = NO;
431 | label.textAlignment = RNLabelAlignmentCenter;
432 | label.opaque = NO;
433 | label.backgroundColor = [UIColor clearColor];
434 | label.textColor = self.labelColor;
435 | label.font = self.labelFont;
436 | label.text = self.labelText;
437 | [self addSubview:label];
438 |
439 | detailsLabel = [[UILabel alloc] initWithFrame:self.bounds];
440 | detailsLabel.font = self.detailsLabelFont;
441 | detailsLabel.adjustsFontSizeToFitWidth = NO;
442 | detailsLabel.textAlignment = RNLabelAlignmentCenter;
443 | detailsLabel.opaque = NO;
444 | detailsLabel.backgroundColor = [UIColor clearColor];
445 | detailsLabel.textColor = self.detailsLabelColor;
446 | detailsLabel.numberOfLines = 0;
447 | detailsLabel.font = self.detailsLabelFont;
448 | detailsLabel.text = self.detailsLabelText;
449 | [self addSubview:detailsLabel];
450 | }
451 |
452 | - (void)updateIndicators {
453 |
454 | BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]];
455 | BOOL isRoundIndicator = [indicator isKindOfClass:[RNRoundProgressView class]];
456 |
457 | if (mode == RNActivityViewModeIndeterminate && !isActivityIndicator) {
458 | // Update to indeterminate indicator
459 | [indicator removeFromSuperview];
460 | self.indicator = [[UIActivityIndicatorView alloc]
461 | initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
462 | [(UIActivityIndicatorView *)indicator startAnimating];
463 | [self addSubview:indicator];
464 | }
465 | else if (mode == RNActivityViewModeDeterminateHorizontalBar) {
466 | // Update to bar determinate indicator
467 | [indicator removeFromSuperview];
468 | self.indicator = [[RNBarProgressView alloc] init];
469 | [self addSubview:indicator];
470 | }
471 | else if (mode == RNActivityViewModeDeterminate || mode == RNActivityViewModeAnnularDeterminate) {
472 | if (!isRoundIndicator) {
473 | // Update to determinante indicator
474 | [indicator removeFromSuperview];
475 | self.indicator = [[RNRoundProgressView alloc] init];
476 | [self addSubview:indicator];
477 | }
478 | if (mode == RNActivityViewModeAnnularDeterminate) {
479 | [(RNRoundProgressView *)indicator setAnnular:YES];
480 | }
481 | }
482 | else if (mode == RNActivityViewModeCustomView && customView != indicator) {
483 | // Update custom view indicator
484 | [indicator removeFromSuperview];
485 | self.indicator = customView;
486 | [self addSubview:indicator];
487 | } else if (mode == RNActivityViewModeText) {
488 | [indicator removeFromSuperview];
489 | self.indicator = nil;
490 | }
491 | }
492 |
493 | #pragma mark - Layout
494 |
495 | - (void)layoutSubviews {
496 |
497 | // Entirely cover the parent view
498 | UIView *parent = self.superview;
499 | if (parent) {
500 | self.frame = parent.bounds;
501 | }
502 | CGRect bounds = self.bounds;
503 |
504 | // Determine the total widt and height needed
505 | CGFloat maxWidth = bounds.size.width - 4 * margin;
506 | CGSize totalSize = CGSizeZero;
507 |
508 | CGRect indicatorF = indicator.bounds;
509 | indicatorF.size.width = MIN(indicatorF.size.width, maxWidth);
510 | totalSize.width = MAX(totalSize.width, indicatorF.size.width);
511 | totalSize.height += indicatorF.size.height;
512 |
513 | CGSize labelSize = MB_TEXTSIZE(label.text, label.font);
514 | labelSize.width = MIN(labelSize.width, maxWidth);
515 | totalSize.width = MAX(totalSize.width, labelSize.width);
516 | totalSize.height += labelSize.height;
517 | if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
518 | totalSize.height += kPadding;
519 | }
520 |
521 | CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin;
522 | CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
523 | CGSize detailsLabelSize = MB_MULTILINE_TEXTSIZE(detailsLabel.text, detailsLabel.font, maxSize, detailsLabel.lineBreakMode);
524 | totalSize.width = MAX(totalSize.width, detailsLabelSize.width);
525 | totalSize.height += detailsLabelSize.height;
526 | if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
527 | totalSize.height += kPadding;
528 | }
529 |
530 | totalSize.width += 2 * margin;
531 | totalSize.height += 2 * margin;
532 |
533 | // Position elements
534 | CGFloat yPos = round(((bounds.size.height - totalSize.height) / 2)) + margin + yOffset;
535 | CGFloat xPos = xOffset;
536 | indicatorF.origin.y = yPos;
537 | indicatorF.origin.x = round((bounds.size.width - indicatorF.size.width) / 2) + xPos;
538 | indicator.frame = indicatorF;
539 | yPos += indicatorF.size.height;
540 |
541 | if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
542 | yPos += kPadding;
543 | }
544 | CGRect labelF;
545 | labelF.origin.y = yPos;
546 | labelF.origin.x = round((bounds.size.width - labelSize.width) / 2) + xPos;
547 | labelF.size = labelSize;
548 | label.frame = labelF;
549 | yPos += labelF.size.height;
550 |
551 | if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
552 | yPos += kPadding;
553 | }
554 | CGRect detailsLabelF;
555 | detailsLabelF.origin.y = yPos;
556 | detailsLabelF.origin.x = round((bounds.size.width - detailsLabelSize.width) / 2) + xPos;
557 | detailsLabelF.size = detailsLabelSize;
558 | detailsLabel.frame = detailsLabelF;
559 |
560 | // Enforce minsize and quare rules
561 | if (square) {
562 | CGFloat max = MAX(totalSize.width, totalSize.height);
563 | if (max <= bounds.size.width - 2 * margin) {
564 | totalSize.width = max;
565 | }
566 | if (max <= bounds.size.height - 2 * margin) {
567 | totalSize.height = max;
568 | }
569 | }
570 | if (totalSize.width < minSize.width) {
571 | totalSize.width = minSize.width;
572 | }
573 | if (totalSize.height < minSize.height) {
574 | totalSize.height = minSize.height;
575 | }
576 |
577 | self.size = totalSize;
578 | }
579 |
580 | #pragma mark BG Drawing
581 |
582 | - (void)drawRect:(CGRect)rect {
583 |
584 | CGContextRef context = UIGraphicsGetCurrentContext();
585 | UIGraphicsPushContext(context);
586 |
587 | if (self.dimBackground) {
588 | //Gradient colours
589 | size_t gradLocationsNum = 2;
590 | CGFloat gradLocations[2] = {0.0f, 1.0f};
591 | CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f};
592 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
593 | CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);
594 | CGColorSpaceRelease(colorSpace);
595 | //Gradient center
596 | CGPoint gradCenter= CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
597 | //Gradient radius
598 | float gradRadius = MIN(self.bounds.size.width , self.bounds.size.height) ;
599 | //Gradient draw
600 | CGContextDrawRadialGradient (context, gradient, gradCenter,
601 | 0, gradCenter, gradRadius,
602 | kCGGradientDrawsAfterEndLocation);
603 | CGGradientRelease(gradient);
604 | }
605 |
606 | // Set background rect color
607 | if (self.color) {
608 | CGContextSetFillColorWithColor(context, self.color.CGColor);
609 | } else {
610 | CGContextSetGrayFillColor(context, 0.0f, self.opacity);
611 | }
612 |
613 |
614 | // Center HUD
615 | CGRect allRect = self.bounds;
616 | // Draw rounded HUD backgroud rect
617 | CGRect boxRect = CGRectMake(round((allRect.size.width - size.width) / 2) + self.xOffset,
618 | round((allRect.size.height - size.height) / 2) + self.yOffset, size.width, size.height);
619 | float radius = self.cornerRadius;
620 | CGContextBeginPath(context);
621 | CGContextMoveToPoint(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect));
622 | CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0);
623 | CGContextAddArc(context, CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0);
624 | CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0);
625 | CGContextAddArc(context, CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0);
626 | CGContextClosePath(context);
627 | CGContextFillPath(context);
628 |
629 | UIGraphicsPopContext();
630 | }
631 |
632 | #pragma mark - KVO
633 |
634 | - (void)registerForKVO {
635 | for (NSString *keyPath in [self observableKeypaths]) {
636 | [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
637 | }
638 | }
639 |
640 | - (void)unregisterFromKVO {
641 | for (NSString *keyPath in [self observableKeypaths]) {
642 | [self removeObserver:self forKeyPath:keyPath];
643 | }
644 | }
645 |
646 | - (NSArray *)observableKeypaths {
647 | return [NSArray arrayWithObjects:@"mode", @"customView", @"labelText", @"labelFont", @"labelColor",
648 | @"detailsLabelText", @"detailsLabelFont", @"detailsLabelColor", @"progress", nil];
649 | }
650 |
651 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
652 | if (![NSThread isMainThread]) {
653 | [self performSelectorOnMainThread:@selector(updateUIForKeypath:) withObject:keyPath waitUntilDone:NO];
654 | } else {
655 | [self updateUIForKeypath:keyPath];
656 | }
657 | }
658 |
659 | - (void)updateUIForKeypath:(NSString *)keyPath {
660 | if ([keyPath isEqualToString:@"mode"] || [keyPath isEqualToString:@"customView"]) {
661 | [self updateIndicators];
662 | } else if ([keyPath isEqualToString:@"labelText"]) {
663 | label.text = self.labelText;
664 | } else if ([keyPath isEqualToString:@"labelFont"]) {
665 | label.font = self.labelFont;
666 | } else if ([keyPath isEqualToString:@"labelColor"]) {
667 | label.textColor = self.labelColor;
668 | } else if ([keyPath isEqualToString:@"detailsLabelText"]) {
669 | detailsLabel.text = self.detailsLabelText;
670 | } else if ([keyPath isEqualToString:@"detailsLabelFont"]) {
671 | detailsLabel.font = self.detailsLabelFont;
672 | } else if ([keyPath isEqualToString:@"detailsLabelColor"]) {
673 | detailsLabel.textColor = self.detailsLabelColor;
674 | } else if ([keyPath isEqualToString:@"progress"]) {
675 | if ([indicator respondsToSelector:@selector(setProgress:)]) {
676 | [(id)indicator setValue:@(progress) forKey:@"progress"];
677 | }
678 | return;
679 | }
680 | [self setNeedsLayout];
681 | [self setNeedsDisplay];
682 | }
683 |
684 | #pragma mark - Notifications
685 |
686 | - (void)registerForNotifications {
687 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
688 | [nc addObserver:self selector:@selector(deviceOrientationDidChange:)
689 | name:UIDeviceOrientationDidChangeNotification object:nil];
690 | }
691 |
692 | - (void)unregisterFromNotifications {
693 | [[NSNotificationCenter defaultCenter] removeObserver:self];
694 | }
695 |
696 | - (void)deviceOrientationDidChange:(NSNotification *)notification {
697 | UIView *superview = self.superview;
698 | if (!superview) {
699 | return;
700 | } else if ([superview isKindOfClass:[UIWindow class]]) {
701 | [self setTransformForCurrentOrientation:YES];
702 | } else {
703 | self.frame = self.superview.bounds;
704 | [self setNeedsDisplay];
705 | }
706 | }
707 |
708 | - (void)setTransformForCurrentOrientation:(BOOL)animated {
709 | // Stay in sync with the superview
710 | if (self.superview) {
711 | self.bounds = self.superview.bounds;
712 | [self setNeedsDisplay];
713 | }
714 |
715 | UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
716 | CGFloat radians = 0;
717 | if (UIInterfaceOrientationIsLandscape(orientation)) {
718 | if (orientation == UIInterfaceOrientationLandscapeLeft) { radians = -(CGFloat)M_PI_2; }
719 | else { radians = (CGFloat)M_PI_2; }
720 | // Window coordinates differ!
721 | self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width);
722 | } else {
723 | if (orientation == UIInterfaceOrientationPortraitUpsideDown) { radians = (CGFloat)M_PI; }
724 | else { radians = 0; }
725 | }
726 | rotationTransform = CGAffineTransformMakeRotation(radians);
727 |
728 | if (animated) {
729 | [UIView beginAnimations:nil context:nil];
730 | }
731 | [self setTransform:rotationTransform];
732 | if (animated) {
733 | [UIView commitAnimations];
734 | }
735 | }
736 |
737 | @end
738 |
739 |
740 | @implementation RNRoundProgressView
741 |
742 | #pragma mark - Lifecycle
743 |
744 | - (id)init {
745 | return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)];
746 | }
747 |
748 | - (id)initWithFrame:(CGRect)frame {
749 | self = [super initWithFrame:frame];
750 | if (self) {
751 | self.backgroundColor = [UIColor clearColor];
752 | self.opaque = NO;
753 | _progress = 0.f;
754 | _annular = NO;
755 | _progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f];
756 | _backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f];
757 | [self registerForKVO];
758 | }
759 | return self;
760 | }
761 |
762 | - (void)dealloc {
763 | [self unregisterFromKVO];
764 | }
765 |
766 | #pragma mark - Drawing
767 |
768 | - (void)drawRect:(CGRect)rect {
769 |
770 | CGRect allRect = self.bounds;
771 | CGRect circleRect = CGRectInset(allRect, 2.0f, 2.0f);
772 | CGContextRef context = UIGraphicsGetCurrentContext();
773 |
774 | if (_annular) {
775 | // Draw background
776 | CGFloat lineWidth = 5.f;
777 | UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath];
778 | processBackgroundPath.lineWidth = lineWidth;
779 | processBackgroundPath.lineCapStyle = kCGLineCapRound;
780 | CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
781 | CGFloat radius = (self.bounds.size.width - lineWidth)/2;
782 | CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
783 | CGFloat endAngle = (2 * (float)M_PI) + startAngle;
784 | [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
785 | [_backgroundTintColor set];
786 | [processBackgroundPath stroke];
787 | // Draw progress
788 | UIBezierPath *processPath = [UIBezierPath bezierPath];
789 | processPath.lineCapStyle = kCGLineCapRound;
790 | processPath.lineWidth = lineWidth;
791 | endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
792 | [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
793 | [_progressTintColor set];
794 | [processPath stroke];
795 | } else {
796 | // Draw background
797 | [_progressTintColor setStroke];
798 | [_backgroundTintColor setFill];
799 | CGContextSetLineWidth(context, 2.0f);
800 | CGContextFillEllipseInRect(context, circleRect);
801 | CGContextStrokeEllipseInRect(context, circleRect);
802 | // Draw progress
803 | CGPoint center = CGPointMake(allRect.size.width / 2, allRect.size.height / 2);
804 | CGFloat radius = (allRect.size.width - 4) / 2;
805 | CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees
806 | CGFloat endAngle = (self.progress * 2 * (float)M_PI) + startAngle;
807 | CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); // white
808 | CGContextMoveToPoint(context, center.x, center.y);
809 | CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
810 | CGContextClosePath(context);
811 | CGContextFillPath(context);
812 | }
813 | }
814 |
815 | #pragma mark - KVO
816 |
817 | - (void)registerForKVO {
818 | for (NSString *keyPath in [self observableKeypaths]) {
819 | [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
820 | }
821 | }
822 |
823 | - (void)unregisterFromKVO {
824 | for (NSString *keyPath in [self observableKeypaths]) {
825 | [self removeObserver:self forKeyPath:keyPath];
826 | }
827 | }
828 |
829 | - (NSArray *)observableKeypaths {
830 | return [NSArray arrayWithObjects:@"progressTintColor", @"backgroundTintColor", @"progress", @"annular", nil];
831 | }
832 |
833 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
834 | [self setNeedsDisplay];
835 | }
836 |
837 | @end
838 |
839 |
840 | @implementation RNBarProgressView
841 |
842 | #pragma mark - Lifecycle
843 |
844 | - (id)init {
845 | return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)];
846 | }
847 |
848 | - (id)initWithFrame:(CGRect)frame {
849 | self = [super initWithFrame:frame];
850 | if (self) {
851 | _progress = 0.f;
852 | _lineColor = [UIColor whiteColor];
853 | _progressColor = [UIColor whiteColor];
854 | _progressRemainingColor = [UIColor clearColor];
855 | self.backgroundColor = [UIColor clearColor];
856 | self.opaque = NO;
857 | [self registerForKVO];
858 | }
859 | return self;
860 | }
861 |
862 | - (void)dealloc {
863 | [self unregisterFromKVO];
864 | }
865 |
866 | #pragma mark - Drawing
867 |
868 | - (void)drawRect:(CGRect)rect {
869 | CGContextRef context = UIGraphicsGetCurrentContext();
870 |
871 | CGContextSetLineWidth(context, 2);
872 | CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]);
873 | CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]);
874 |
875 | // Draw background
876 | float radius = (rect.size.height / 2) - 2;
877 | CGContextMoveToPoint(context, 2, rect.size.height/2);
878 | CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
879 | CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
880 | CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
881 | CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
882 | CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
883 | CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
884 | CGContextFillPath(context);
885 |
886 | // Draw border
887 | CGContextMoveToPoint(context, 2, rect.size.height/2);
888 | CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius);
889 | CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2);
890 | CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius);
891 | CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius);
892 | CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2);
893 | CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius);
894 | CGContextStrokePath(context);
895 |
896 | CGContextSetFillColorWithColor(context, [_progressColor CGColor]);
897 | radius = radius - 2;
898 | float amount = self.progress * rect.size.width;
899 |
900 | // Progress in the middle area
901 | if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) {
902 | CGContextMoveToPoint(context, 4, rect.size.height/2);
903 | CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
904 | CGContextAddLineToPoint(context, amount, 4);
905 | CGContextAddLineToPoint(context, amount, radius + 4);
906 |
907 | CGContextMoveToPoint(context, 4, rect.size.height/2);
908 | CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
909 | CGContextAddLineToPoint(context, amount, rect.size.height - 4);
910 | CGContextAddLineToPoint(context, amount, radius + 4);
911 |
912 | CGContextFillPath(context);
913 | }
914 |
915 | // Progress in the right arc
916 | else if (amount > radius + 4) {
917 | float x = amount - (rect.size.width - radius - 4);
918 |
919 | CGContextMoveToPoint(context, 4, rect.size.height/2);
920 | CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
921 | CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4);
922 | float angle = -acos(x/radius);
923 | if (isnan(angle)) angle = 0;
924 | CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0);
925 | CGContextAddLineToPoint(context, amount, rect.size.height/2);
926 |
927 | CGContextMoveToPoint(context, 4, rect.size.height/2);
928 | CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
929 | CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4);
930 | angle = acos(x/radius);
931 | if (isnan(angle)) angle = 0;
932 | CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1);
933 | CGContextAddLineToPoint(context, amount, rect.size.height/2);
934 |
935 | CGContextFillPath(context);
936 | }
937 |
938 | // Progress is in the left arc
939 | else if (amount < radius + 4 && amount > 0) {
940 | CGContextMoveToPoint(context, 4, rect.size.height/2);
941 | CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius);
942 | CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
943 |
944 | CGContextMoveToPoint(context, 4, rect.size.height/2);
945 | CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius);
946 | CGContextAddLineToPoint(context, radius + 4, rect.size.height/2);
947 |
948 | CGContextFillPath(context);
949 | }
950 | }
951 |
952 | #pragma mark - KVO
953 |
954 | - (void)registerForKVO {
955 | for (NSString *keyPath in [self observableKeypaths]) {
956 | [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
957 | }
958 | }
959 |
960 | - (void)unregisterFromKVO {
961 | for (NSString *keyPath in [self observableKeypaths]) {
962 | [self removeObserver:self forKeyPath:keyPath];
963 | }
964 | }
965 |
966 | - (NSArray *)observableKeypaths {
967 | return [NSArray arrayWithObjects:@"lineColor", @"progressRemainingColor", @"progressColor", @"progress", nil];
968 | }
969 |
970 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
971 | [self setNeedsDisplay];
972 | }
973 |
974 | @end
975 |
--------------------------------------------------------------------------------
/CustomImagePicker/UIView+RNActivityView.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+RNActivityView.h
3 | // HudDemo
4 | //
5 | // Created by Romilson Nunes on 09/07/14.
6 | // Copyright (c) 2014 Matej Bukovinski. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RNActivityView.h"
11 |
12 |
13 | @interface UIView (RNActivityView)
14 |
15 | @property(nonatomic, readonly) RNActivityView * activityView;
16 |
17 |
18 | -(void)showActivityView;
19 | -(void)showActivityViewWithLabel:(NSString *)text;
20 | -(void)showActivityViewWithLabel:(NSString *)text detailLabel:(NSString *)detail;
21 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail;
22 |
23 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail whileExecuting:(SEL)method onTarget:(id)target;
24 |
25 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail whileExecutingBlock:(dispatch_block_t)block;
26 |
27 |
28 | - (void) hideActivityView;
29 | - (void) hideActivityViewWithAfterDelay:(NSTimeInterval)delay;
30 |
31 | - (void) showActivityViewWithLabel:(NSString *)text image:(UIImage *)image;
32 | - (void) showActivityViewWithLabel:(NSString *)text customView:(UIView *)view;
33 |
34 |
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/CustomImagePicker/UIView+RNActivityView.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+RNActivityView.m
3 | // HudDemo
4 | //
5 | // Created by Romilson Nunes on 09/07/14.
6 | // Copyright (c) 2014 Matej Bukovinski. All rights reserved.
7 | //
8 |
9 | #import "UIView+RNActivityView.h"
10 |
11 | #import
12 | #import
13 |
14 | #define RNLoadingHelperKey @"RNLoadingHelperKey"
15 | #define RNDateLastUpadaKey @"RNDateLastUpadaKey"
16 |
17 | @implementation UIView (RNActivityView)
18 |
19 | - (void)rn_dealloc {
20 | [self destroyActivityView];
21 |
22 | //this calls original dealloc method
23 | [self rn_dealloc];
24 | }
25 |
26 |
27 | - (void)rn_didMoveToSuperview {
28 | if (!self.superview || !self.window) {
29 | [self destroyActivityView];
30 | }
31 |
32 | [self rn_didMoveToSuperview];
33 | }
34 |
35 | - (void)rn_willMoveToSuperview:(UIView *)newSuperview {
36 |
37 | if (!self.window) {
38 | [self rn_activityView].delegate = nil;
39 |
40 | [self destroyActivityView];
41 | }
42 |
43 | [self rn_willMoveToSuperview:newSuperview];
44 | }
45 |
46 | - (void) destroyActivityView {
47 | @synchronized(self) {
48 | if (self.rn_activityView) {
49 |
50 | [NSObject cancelPreviousPerformRequestsWithTarget:self.rn_activityView];
51 | self.rn_activityView.delegate = nil;
52 |
53 | @try {
54 | [self.rn_activityView removeFromSuperview];
55 | }
56 | @catch (NSException *exception) {
57 | }
58 |
59 | [self setActivityView:nil];
60 | }
61 | }
62 | }
63 |
64 |
65 |
66 |
67 | -(RNActivityView *)rn_activityView {
68 | return objc_getAssociatedObject(self, RNLoadingHelperKey);
69 | }
70 |
71 | - (void)swizzleMethod:(SEL)originalSelector withMethod:(SEL)swizzledSelector {
72 |
73 | Method originalMethod = class_getInstanceMethod([self class], originalSelector);
74 | Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
75 |
76 | BOOL didAddMethod =
77 | class_addMethod([self class],
78 | originalSelector,
79 | method_getImplementation(swizzledMethod),
80 | method_getTypeEncoding(swizzledMethod));
81 |
82 | if (didAddMethod) {
83 | class_replaceMethod([self class],
84 | swizzledSelector,
85 | method_getImplementation(originalMethod),
86 | method_getTypeEncoding(originalMethod));
87 | } else {
88 | method_exchangeImplementations(originalMethod, swizzledMethod);
89 | }
90 |
91 | }
92 |
93 |
94 |
95 | #pragma mark - Public Methods
96 |
97 | -(RNActivityView *)activityView {
98 | RNActivityView *activityView = objc_getAssociatedObject(self, RNLoadingHelperKey);
99 |
100 | if (!activityView) {
101 | activityView = [[RNActivityView alloc] initWithView:self];
102 | activityView.delegate = self;
103 | [self setActivityView:activityView];
104 |
105 | [self swizzleMethod:NSSelectorFromString(@"dealloc") withMethod:@selector(rn_dealloc)];
106 | [self swizzleMethod:NSSelectorFromString(@"didMoveToSuperview") withMethod:@selector(rn_didMoveToSuperview)];
107 | [self swizzleMethod:NSSelectorFromString(@"willMoveToSuperview") withMethod:@selector(rn_willMoveToSuperview:)];
108 |
109 |
110 |
111 | }
112 | if (!activityView.superview) {
113 | [self addSubview:activityView];
114 | }
115 | return activityView;
116 | }
117 |
118 | -(void)setActivityView:(RNActivityView *)activityView {
119 | objc_setAssociatedObject(self, RNLoadingHelperKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
120 | }
121 |
122 | -(void)showActivityView {
123 | [self.activityView show:YES];
124 | }
125 |
126 | -(void)showActivityViewWithLabel:(NSString *)text {
127 | [self showActivityViewWithLabel:text detailLabel:nil];
128 | }
129 |
130 | -(void)showActivityViewWithLabel:(NSString *)text detailLabel:(NSString *)detail {
131 | [self showActivityViewWithMode:self.activityView.mode label:text detailLabel:detail];
132 | }
133 |
134 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail; {
135 |
136 | [self.activityView setupDefaultValues];
137 | self.activityView.labelText = text;
138 | self.activityView.detailsLabelText = detail;
139 | self.activityView.mode = mode;
140 | self.activityView.dimBackground = NO;
141 |
142 | [self showActivityView];
143 | }
144 |
145 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail whileExecuting:(SEL)method onTarget:(id)target {
146 |
147 | [self.activityView setupDefaultValues];
148 | self.activityView.labelText = text;
149 | self.activityView.detailsLabelText = detail;
150 | self.activityView.mode = mode;
151 | self.activityView.dimBackground = YES;
152 |
153 | [self.activityView showWhileExecuting:method onTarget:target withObject:nil animated:YES];
154 | }
155 |
156 | -(void)showActivityViewWithMode:(RNActivityViewMode)mode label:(NSString *)text detailLabel:(NSString *)detail whileExecutingBlock:(dispatch_block_t)block {
157 |
158 | [self.activityView setupDefaultValues];
159 | self.activityView.labelText = text;
160 | self.activityView.detailsLabelText = detail;
161 | self.activityView.mode = mode;
162 | self.activityView.dimBackground = YES;
163 |
164 | [self.activityView showAnimated:YES whileExecutingBlock:block];
165 | }
166 |
167 |
168 | - (void) showActivityViewWithLabel:(NSString *)text image:(UIImage *)image {
169 | UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
170 | [self showActivityViewWithLabel:text customView:imageView];
171 | }
172 |
173 |
174 | - (void) showActivityViewWithLabel:(NSString *)text customView:(UIView *)view {
175 | [self.activityView setupDefaultValues];
176 | self.activityView.customView = view;
177 | self.activityView.mode = RNActivityViewModeCustomView;
178 | self.activityView.labelText = text;
179 |
180 | [self showActivityView];
181 | }
182 |
183 |
184 | - (void) hideActivityView {
185 | [self hideActivityViewWithAfterDelay:0];
186 | }
187 |
188 | - (void) hideActivityViewWithAfterDelay:(NSTimeInterval)delay {
189 | [self.activityView hide:YES afterDelay:delay];
190 | }
191 |
192 |
193 |
194 | #pragma mark -
195 | #pragma mark RNActivityViewDelegate methods
196 |
197 | - (void)hudWasHidden:(RNActivityView *)hud {
198 | // Remove HUD from screen when the HUD was hidded
199 | [hud removeFromSuperview];
200 | self.activityView = nil;
201 | }
202 |
203 |
204 |
205 | @end
206 |
--------------------------------------------------------------------------------
/CustomImagePicker/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CustomeImagePicker.h"
11 | @interface ViewController : UIViewController
12 | @property(nonatomic, weak) IBOutlet UIImageView *imageView1;
13 | @property(nonatomic, weak) IBOutlet UIImageView *imageView2;
14 | @property(nonatomic, weak) IBOutlet UIImageView *imageView3;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/CustomImagePicker/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "UIView+RNActivityView.h"
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 | @synthesize imageView1,imageView2,imageView3;
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view from its nib.
20 | }
21 |
22 | - (void)didReceiveMemoryWarning {
23 | [super didReceiveMemoryWarning];
24 | // Dispose of any resources that can be recreated.
25 | }
26 |
27 | -(IBAction)getPhoto:(id)sender
28 | {
29 | CustomeImagePicker *cip = [[CustomeImagePicker alloc] init];
30 | cip.delegate = self;
31 | [cip setHideSkipButton:NO];
32 | [cip setHideNextButton:NO];
33 | [cip setMaxPhotos:MAX_ALLOWED_PICK];
34 | [cip setShowOnlyPhotosWithGPS:NO];
35 |
36 | [self presentViewController:cip animated:YES completion:^{
37 | }
38 | ];
39 | }
40 |
41 | -(void) imageSelected:(NSArray *)arrayOfImages
42 | {
43 |
44 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
45 | dispatch_async(dispatch_get_main_queue(), ^{
46 | [self.view showActivityView];
47 | }); // Main Queue to Display the Activity View
48 | int count = 0;
49 | for(NSString *imageURLString in arrayOfImages)
50 | {
51 | // Asset URLs
52 | ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
53 | [assetsLibrary assetForURL:[NSURL URLWithString:imageURLString] resultBlock:^(ALAsset *asset) {
54 | ALAssetRepresentation *representation = [asset defaultRepresentation];
55 | CGImageRef imageRef = [representation fullScreenImage];
56 | UIImage *image = [UIImage imageWithCGImage:imageRef];
57 | if (imageRef) {
58 | dispatch_async(dispatch_get_main_queue(), ^{
59 | if(count==0)
60 | {
61 | [imageView1 setImage:image];
62 | }
63 | if(count==1)
64 | {
65 | [imageView2 setImage:image];
66 | }
67 | if(count==2)
68 | {
69 | [imageView3 setImage:image];
70 | }
71 | });
72 | } // Valid Image URL
73 | } failureBlock:^(NSError *error) {
74 | }];
75 | count++;
76 | } // All Images I got
77 | dispatch_async(dispatch_get_main_queue(), ^{
78 | [self.view hideActivityView];
79 | });
80 | }); // Queue for reloading all images
81 | }
82 | -(void) imageSelectionCancelled
83 | {
84 |
85 | }
86 |
87 |
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/CustomImagePicker/ViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/CustomImagePicker/YCameraViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoShapViewController.h
3 | // NoshedItStaging
4 | //
5 | // Created by yuvraj on 08/01/14.
6 | // Copyright (c) 2014 limbasiya.nirav@gmail.com. All rights reserved.
7 | //
8 |
9 | //
10 | // ARC Helper
11 | #ifndef ah_retain
12 | #if __has_feature(objc_arc)
13 | #define ah_retain self
14 | #define ah_dealloc self
15 | #define release self
16 | #define autorelease self
17 | #else
18 | #define ah_retain retain
19 | #define ah_dealloc dealloc
20 | #define __bridge
21 | #endif
22 | #endif
23 |
24 | // ARC Helper ends
25 |
26 | #import
27 | #import
28 | #import
29 | #import "CameraFocusSquare.h"
30 | #import "OLGhostAlertView.h"
31 | #import
32 | @protocol YCameraViewControllerDelegate;
33 |
34 | @interface YCameraViewController : UIViewController {
35 |
36 | UIImagePickerController *imgPicker;
37 | BOOL pickerDidShow;
38 |
39 | //Today Implementation
40 | BOOL FrontCamera;
41 | BOOL haveImage;
42 | BOOL initializeCamera, photoFromCam;
43 | AVCaptureSession *session;
44 | AVCaptureDeviceInput *input;
45 | AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
46 | AVCaptureStillImageOutput *stillImageOutput;
47 | UIImage *croppedImageWithoutOrientation;
48 | CameraFocusSquare *camFocus;
49 | NSURL *assetURLToSend;
50 | NSDictionary *metadata;
51 | }
52 | @property (nonatomic, readwrite) BOOL dontAllowResetRestaurant;
53 | @property (nonatomic, assign) id delegate;
54 |
55 | #pragma mark -
56 | @property (nonatomic, strong) IBOutlet UIButton *photoCaptureButton;
57 | @property (nonatomic, strong) IBOutlet UIButton *cancelButton;
58 | @property (nonatomic, strong) IBOutlet UIButton *cameraToggleButton;
59 | @property (nonatomic, strong) IBOutlet UIButton *libraryToggleButton;
60 | @property (nonatomic, strong) IBOutlet UIButton *flashToggleButton;
61 | @property (retain, nonatomic) IBOutlet UIImageView *ImgViewGrid;
62 | @property (nonatomic, strong) IBOutlet UIView *photoBar;
63 | @property (nonatomic, strong) IBOutlet UIView *topBar;
64 | @property (retain, nonatomic) IBOutlet UIView *imagePreview;
65 | @property (retain, nonatomic) IBOutlet UIImageView *captureImage;
66 | @property (nonatomic, weak) IBOutlet UISlider *zoomFactor;
67 | @property (nonatomic,strong) CLLocation *currentUserLocation;
68 | @end
69 |
70 | @protocol YCameraViewControllerDelegate
71 | - (void)didFinishPickingImage:(UIImage *)image metadata:(NSDictionary*)metadata;
72 | - (void)yCameraControllerDidCancel;
73 | - (void)yCameraControllerdidSkipped;
74 | @end
75 |
--------------------------------------------------------------------------------
/CustomImagePicker/YCameraViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoShapViewController.m
3 | // NoshedItStaging
4 | //
5 | // Created by yuvraj on 08/01/14.
6 | // Copyright (c) 2014 limbasiya.nirav@gmail.com. All rights reserved.
7 | //
8 |
9 | #import "YCameraViewController.h"
10 | #import "AppDelegate.h"
11 | #import
12 |
13 | #define DegreesToRadians(x) ((x) * M_PI / 180.0)
14 |
15 | @interface YCameraViewController (){
16 | UIInterfaceOrientation orientationLast, orientationAfterProcess;
17 | CMMotionManager *motionManager;
18 | }
19 | @end
20 |
21 | @implementation YCameraViewController
22 | @synthesize delegate,zoomFactor,currentUserLocation;
23 |
24 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
25 | {
26 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
27 | if (self) {
28 | // Custom initialization
29 | }
30 | return self;
31 | }
32 |
33 | - (void)viewDidLoad
34 | {
35 | [super viewDidLoad];
36 |
37 | // if ([self respondsToSelector:@selector(edgesForExtendedLayout)]){
38 | // self.edgesForExtendedLayout = UIRectEdgeNone;
39 | // }
40 |
41 | self.navigationController.navigationBarHidden = YES;
42 | [self.navigationController setNavigationBarHidden:YES];
43 |
44 | // Do any additional setup after loading the view.
45 | pickerDidShow = NO;
46 |
47 | FrontCamera = NO;
48 | self.captureImage.hidden = YES;
49 |
50 | // Setup UIImagePicker Controller
51 | imgPicker = [[UIImagePickerController alloc] init];
52 | imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
53 | imgPicker.delegate = self;
54 | imgPicker.allowsEditing = YES;
55 |
56 | croppedImageWithoutOrientation = [[UIImage alloc] init];
57 |
58 | initializeCamera = YES;
59 | photoFromCam = YES;
60 | self.flashToggleButton.selected=NO;
61 | // Initialize Motion Manager
62 | [self initializeMotionManager];
63 | camFocus = [[CameraFocusSquare alloc] init];
64 | }
65 |
66 | - (void)viewWillAppear:(BOOL)animated{
67 | [super viewWillAppear:animated];
68 | [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
69 | }
70 |
71 | - (void)viewDidAppear:(BOOL)animated{
72 | [super viewDidAppear:animated];
73 |
74 | if (initializeCamera){
75 | initializeCamera = NO;
76 |
77 | // Initialize camera
78 | [self initializeCamera];
79 | }
80 |
81 | }
82 |
83 | - (void)viewWillDisappear:(BOOL)animated{
84 | [super viewWillDisappear:animated];
85 | [session stopRunning];
86 | [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
87 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
88 | }
89 |
90 | - (void)didReceiveMemoryWarning
91 | {
92 | [super didReceiveMemoryWarning];
93 | // Dispose of any resources that can be recreated.
94 | }
95 |
96 | -(void) dealloc
97 | {
98 | [_imagePreview release];
99 | [_captureImage release];
100 | [imgPicker release];
101 | imgPicker = nil;
102 | camFocus = Nil;
103 | if (session)
104 | [session release], session=nil;
105 |
106 | if (captureVideoPreviewLayer)
107 | [captureVideoPreviewLayer release], captureVideoPreviewLayer=nil;
108 |
109 | if (stillImageOutput)
110 | [stillImageOutput release], stillImageOutput=nil;
111 | }
112 |
113 | #pragma mark - CoreMotion Task
114 | - (void)initializeMotionManager{
115 | motionManager = [[CMMotionManager alloc] init];
116 | motionManager.accelerometerUpdateInterval = .2;
117 | motionManager.gyroUpdateInterval = .2;
118 |
119 | [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
120 | withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
121 | if (!error) {
122 | [self outputAccelertionData:accelerometerData.acceleration];
123 | }
124 | else{
125 | NSLog(@"%@", error);
126 | }
127 | }];
128 | }
129 |
130 | #pragma mark - UIAccelerometer callback
131 |
132 | - (void)outputAccelertionData:(CMAcceleration)acceleration{
133 | UIInterfaceOrientation orientationNew;
134 |
135 | if (acceleration.x >= 0.75) {
136 | orientationNew = UIInterfaceOrientationLandscapeLeft;
137 | }
138 | else if (acceleration.x <= -0.75) {
139 | orientationNew = UIInterfaceOrientationLandscapeRight;
140 | }
141 | else if (acceleration.y <= -0.75) {
142 | orientationNew = UIInterfaceOrientationPortrait;
143 | }
144 | else if (acceleration.y >= 0.75) {
145 | orientationNew = UIInterfaceOrientationPortraitUpsideDown;
146 | }
147 | else {
148 | // Consider same as last time
149 | return;
150 | }
151 |
152 | if (orientationNew == orientationLast)
153 | return;
154 |
155 | // NSLog(@"Going from %@ to %@!", [[self class] orientationToText:orientationLast], [[self class] orientationToText:orientationNew]);
156 |
157 | orientationLast = orientationNew;
158 | }
159 |
160 | #ifdef DEBUG
161 | +(NSString*)orientationToText:(const UIInterfaceOrientation)ORIENTATION {
162 | switch (ORIENTATION) {
163 | case UIInterfaceOrientationPortrait:
164 | return @"UIInterfaceOrientationPortrait";
165 | case UIInterfaceOrientationPortraitUpsideDown:
166 | return @"UIInterfaceOrientationPortraitUpsideDown";
167 | case UIInterfaceOrientationLandscapeLeft:
168 | return @"UIInterfaceOrientationLandscapeLeft";
169 | case UIInterfaceOrientationLandscapeRight:
170 | return @"UIInterfaceOrientationLandscapeRight";
171 | }
172 | return @"Unknown orientation!";
173 | }
174 | #endif
175 |
176 | #pragma mark - Camera Initialization
177 |
178 | //AVCaptureSession to show live video feed in view
179 | - (void) initializeCamera {
180 | if (session)
181 | [session release], session=nil;
182 |
183 | session = [[AVCaptureSession alloc] init];
184 | // session.sessionPreset = AVCaptureSessionPresetPhoto;
185 | session.sessionPreset = AVCaptureSessionPreset1280x720;
186 | if (captureVideoPreviewLayer)
187 | [captureVideoPreviewLayer release], captureVideoPreviewLayer=nil;
188 |
189 | captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
190 | [captureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
191 |
192 | captureVideoPreviewLayer.frame = self.imagePreview.bounds;
193 | [self.imagePreview.layer addSublayer:captureVideoPreviewLayer];
194 |
195 | UIView *view = [self imagePreview];
196 | CALayer *viewLayer = [view layer];
197 | [viewLayer setMasksToBounds:YES];
198 |
199 | CGRect bounds = [view bounds];
200 | [captureVideoPreviewLayer setFrame:bounds];
201 |
202 | NSArray *devices = [AVCaptureDevice devices];
203 | AVCaptureDevice *frontCamera=nil;
204 | AVCaptureDevice *backCamera=nil;
205 |
206 | // check if device available
207 | if (devices.count==0) {
208 | NSLog(@"No Camera Available");
209 | [self disableCameraDeviceControls];
210 | return;
211 | }
212 |
213 | for (AVCaptureDevice *device in devices) {
214 | if ([device hasMediaType:AVMediaTypeVideo]) {
215 |
216 | if ([device position] == AVCaptureDevicePositionBack) {
217 | NSLog(@"Device position : back");
218 | backCamera = device;
219 | }
220 | else {
221 | NSLog(@"Device position : front");
222 | frontCamera = device;
223 | // if([device isFocusModeSupported:AVCaptureFocusModeAutoFocus])
224 | // {
225 | // if([device lockForConfiguration:NULL])
226 | // {
227 | // [device setFocusMode:AVCaptureFocusModeAutoFocus];
228 | // [device unlockForConfiguration];
229 | // }
230 | // }
231 | }
232 | }
233 | }
234 |
235 | if (!FrontCamera) {
236 |
237 | if ([backCamera hasFlash]){
238 | [backCamera lockForConfiguration:nil];
239 | if (self.flashToggleButton.selected)
240 | [backCamera setFlashMode:AVCaptureFlashModeOn];
241 | else
242 | [backCamera setFlashMode:AVCaptureFlashModeOff];
243 | [backCamera unlockForConfiguration];
244 |
245 | [self.flashToggleButton setEnabled:YES];
246 | }
247 | else{
248 | if ([backCamera isFlashModeSupported:AVCaptureFlashModeOff]) {
249 | [backCamera lockForConfiguration:nil];
250 | [backCamera setFlashMode:AVCaptureFlashModeOff];
251 | [backCamera unlockForConfiguration];
252 | }
253 | [self.flashToggleButton setEnabled:NO];
254 | }
255 |
256 | NSError *error = nil;
257 | input = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error];
258 | if (!input) {
259 | NSLog(@"ERROR: trying to open camera: %@", error);
260 | }
261 | else
262 | {
263 | [session addInput:input];
264 | if (stillImageOutput)
265 | [stillImageOutput release], stillImageOutput=nil;
266 |
267 | stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
268 | [stillImageOutput setHighResolutionStillImageOutputEnabled:YES];
269 | NSDictionary *outputSettings = [[[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil] autorelease];
270 | [stillImageOutput setOutputSettings:outputSettings];
271 |
272 | [session addOutput:stillImageOutput];
273 |
274 | [session startRunning];
275 | }
276 | }
277 |
278 | if (FrontCamera) {
279 | [self.flashToggleButton setEnabled:NO];
280 | NSError *error = nil;
281 | input = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error];
282 | if (!input) {
283 | NSLog(@"ERROR: trying to open camera: %@", error);
284 | }
285 | else
286 | {
287 | [session addInput:input];
288 | if (stillImageOutput)
289 | [stillImageOutput release], stillImageOutput=nil;
290 |
291 | stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
292 | NSDictionary *outputSettings = [[[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil] autorelease];
293 | [stillImageOutput setOutputSettings:outputSettings];
294 |
295 | [session addOutput:stillImageOutput];
296 |
297 | [session startRunning];
298 | }
299 | }
300 |
301 | for(UIGestureRecognizer *gesture in [self.imagePreview gestureRecognizers])
302 | {
303 | [self.imagePreview removeGestureRecognizer:gesture];
304 | }
305 |
306 | UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToFocus:)];
307 | [tapGR setNumberOfTapsRequired:1];
308 | [tapGR setNumberOfTouchesRequired:1];
309 | [tapGR setDelegate:self];
310 | [self.imagePreview addGestureRecognizer:tapGR];
311 |
312 |
313 | if (camFocus)
314 | {
315 | [camFocus removeFromSuperview];
316 | }
317 | camFocus = [[CameraFocusSquare alloc]initWithFrame:CGRectMake(self.imagePreview.center.x-40, self.imagePreview.center.y-40, 80, 80)];
318 | [camFocus setBackgroundColor:[UIColor clearColor]];
319 | [self.imagePreview addSubview:camFocus];
320 | [camFocus setNeedsDisplay];
321 |
322 | [UIView beginAnimations:nil context:NULL];
323 | [UIView setAnimationDuration:1.0];
324 | [camFocus setAlpha:0.0];
325 | [UIView commitAnimations];
326 |
327 | }
328 |
329 |
330 | -(IBAction)zoomChanged:(UISlider*)sender
331 | {
332 | AVCaptureDevice *currentDevice = input.device;
333 | if(sender.value == 0)
334 | {
335 | if ([currentDevice lockForConfiguration:Nil]) {
336 | currentDevice.videoZoomFactor = 1.0;
337 | [currentDevice unlockForConfiguration];
338 | }
339 | }
340 | else
341 | {
342 | if ([currentDevice lockForConfiguration:Nil]) {
343 | currentDevice.videoZoomFactor = 1.0 + sender.value;
344 | [currentDevice unlockForConfiguration];
345 | }
346 | }
347 | }
348 |
349 |
350 | -(void)tapToFocus:(UITapGestureRecognizer *)singleTap{
351 | CGPoint touchPoint = [singleTap locationInView:self.imagePreview];
352 | CGPoint convertedPoint = [captureVideoPreviewLayer captureDevicePointOfInterestForPoint:touchPoint];
353 |
354 |
355 |
356 | if (camFocus)
357 | {
358 | [camFocus removeFromSuperview];
359 | }
360 | camFocus = [[CameraFocusSquare alloc]initWithFrame:CGRectMake(touchPoint.x-40, touchPoint.y-40, 80, 80)];
361 | [camFocus setBackgroundColor:[UIColor clearColor]];
362 | [self.imagePreview addSubview:camFocus];
363 | [camFocus setNeedsDisplay];
364 |
365 | [UIView beginAnimations:nil context:NULL];
366 | [UIView setAnimationDuration:1.5];
367 | [camFocus setAlpha:0.0];
368 | [UIView commitAnimations];
369 |
370 |
371 | AVCaptureDevice *currentDevice = input.device;
372 |
373 |
374 |
375 | if([currentDevice isFocusPointOfInterestSupported] && [currentDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]){
376 | NSError *error = nil;
377 | [currentDevice lockForConfiguration:&error];
378 | if(!error){
379 | [currentDevice setFocusPointOfInterest:convertedPoint];
380 | [currentDevice setFocusMode:AVCaptureFocusModeAutoFocus];
381 | [currentDevice unlockForConfiguration];
382 | NSLog(@"Changed Focus");
383 | }
384 | }
385 | }
386 |
387 | - (IBAction)snapImage:(id)sender {
388 | [self.photoCaptureButton setEnabled:NO];
389 |
390 | if (!haveImage) {
391 | self.captureImage.image = nil; //remove old image from view
392 | self.captureImage.hidden = NO; //show the captured image view
393 | self.imagePreview.hidden = YES; //hide the live video feed
394 | [self capImage];
395 | }
396 | else {
397 | self.captureImage.hidden = YES;
398 | self.imagePreview.hidden = NO;
399 | haveImage = NO;
400 | }
401 | }
402 |
403 | - (void) capImage { //method to capture image from AVCaptureSession video feed
404 | AVCaptureConnection *videoConnection = nil;
405 | for (AVCaptureConnection *connection in stillImageOutput.connections) {
406 |
407 | for (AVCaptureInputPort *port in [connection inputPorts]) {
408 |
409 | if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
410 | videoConnection = connection;
411 | break;
412 | }
413 | }
414 |
415 | if (videoConnection) {
416 | break;
417 | }
418 | }
419 |
420 | [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
421 |
422 | if (imageSampleBuffer != NULL) {
423 |
424 | NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
425 | CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault,
426 | imageSampleBuffer,
427 | kCMAttachmentMode_ShouldPropagate);
428 | metadata = (__bridge NSDictionary*)attachments;
429 |
430 |
431 |
432 | CFMutableDictionaryRef mutable = CFDictionaryCreateMutableCopy(NULL, 0, attachments);
433 | NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
434 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
435 | [formatter setTimeZone:timeZone];
436 | [formatter setDateFormat:@"HH:mm:ss.SS"];
437 | NSDictionary *gpsDict = [NSDictionary dictionaryWithObjectsAndKeys:
438 | [NSNumber numberWithFloat:fabs(currentUserLocation.coordinate.latitude)], kCGImagePropertyGPSLatitude
439 | , ((currentUserLocation.coordinate.latitude >= 0) ? @"N" : @"S"), kCGImagePropertyGPSLatitudeRef
440 | , [NSNumber numberWithFloat:fabs(currentUserLocation.coordinate.longitude)], kCGImagePropertyGPSLongitude
441 | , ((currentUserLocation.coordinate.longitude >= 0) ? @"E" : @"W"), kCGImagePropertyGPSLongitudeRef
442 | , [formatter stringFromDate:[currentUserLocation timestamp]], kCGImagePropertyGPSTimeStamp
443 | , [NSNumber numberWithFloat:fabs(currentUserLocation.altitude)], kCGImagePropertyGPSAltitude
444 | ,[NSNumber numberWithFloat:currentUserLocation.horizontalAccuracy],kCGImagePropertyGPSDOP
445 |
446 | , nil];
447 |
448 |
449 | CFDictionarySetValue(mutable, kCGImagePropertyGPSDictionary, (__bridge void *)gpsDict);
450 |
451 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
452 |
453 | CFStringRef UTI = CGImageSourceGetType(source); //this is the type of image (e.g., public.jpeg)
454 | NSMutableData *dest_data = [NSMutableData data];
455 | CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data,UTI,1,NULL);
456 | if(!destination) {
457 | NSLog(@"***Could not create image destination ***");
458 | }
459 | CGImageDestinationAddImageFromSource(destination,source,0, (CFDictionaryRef) mutable);
460 |
461 | //tell the destination to write the image data and metadata into our data object.
462 | //It will return false if something goes wrong
463 | BOOL success = CGImageDestinationFinalize(destination);
464 |
465 | if(!success) {
466 | NSLog(@"***Could not create data from image destination ***");
467 | }
468 |
469 | CFRelease(destination);
470 | CFRelease(source);
471 | imageData = NULL;
472 | metadata = (__bridge NSDictionary*)mutable;
473 |
474 | // [self processImage:[UIImage imageWithData:imageData]];
475 | [self.captureImage setImage:[UIImage imageWithData:dest_data]];
476 |
477 | [self setCapturedImage];
478 |
479 |
480 | // CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault,
481 | // imageSampleBuffer,
482 | // kCMAttachmentMode_ShouldPropagate);
483 | // NSDictionary *andBack = (__bridge NSDictionary*)attachments;
484 | // ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
485 | // [library writeImageDataToSavedPhotosAlbum:imageData metadata:andBack completionBlock:^(NSURL *assetURL, NSError *error) {
486 | // if (error) {
487 | // [self displayErrorOnMainQueue:error withMessage:@"Save to camera roll failed"];
488 | // }
489 | // }];
490 | //
491 | // if (attachments)
492 | // CFRelease(attachments);
493 | // [library release];
494 | //
495 | // [self.captureImage setImage:[UIImage imageWithData:imageData]];
496 | //
497 | // [self setCapturedImage];
498 | }
499 | }];
500 | }
501 |
502 | - (void)displayErrorOnMainQueue:(NSError *)error withMessage:(NSString *)message
503 | {
504 | dispatch_async(dispatch_get_main_queue(), ^(void) {
505 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@ (%d)", message, (int)[error code]]
506 | message:[error localizedDescription]
507 | delegate:nil
508 | cancelButtonTitle:@"Dismiss"
509 | otherButtonTitles:nil];
510 | [alertView show];
511 | [alertView release];
512 | });
513 | }
514 |
515 | - (UIImage*)imageWithImage:(UIImage *)sourceImage scaledToWidth:(float) i_width
516 | {
517 | float oldWidth = sourceImage.size.width;
518 | float scaleFactor = i_width / oldWidth;
519 |
520 | float newHeight = sourceImage.size.height * scaleFactor;
521 | float newWidth = oldWidth * scaleFactor;
522 |
523 | UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
524 | [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
525 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
526 | UIGraphicsEndImageContext();
527 | return newImage;
528 | }
529 |
530 | - (void) processImage:(UIImage *)image { //process captured image, crop, resize and rotate
531 | haveImage = YES;
532 | photoFromCam = YES;
533 |
534 | // Resize image to 640x640
535 | // Resize image
536 | // NSLog(@"Image size %f and %f",image.size.width,image.size.height);
537 | //
538 | //
539 | // CGRect screenRect = [[UIScreen mainScreen] bounds];
540 | // CGFloat screenWidth = screenRect.size.width;
541 | // CGFloat screenHeight = screenRect.size.height;
542 |
543 |
544 |
545 |
546 | UIImage *smallImage = [self imageWithImage:image scaledToWidth:720]; //UIGraphicsGetImageFromCurrentImageContext();
547 | CGRect cropRect = CGRectMake(0, 0, smallImage.size.width, smallImage.size.height);
548 | CGImageRef imageRef = CGImageCreateWithImageInRect([smallImage CGImage], cropRect);
549 | croppedImageWithoutOrientation = [[UIImage imageWithCGImage:imageRef] copy];
550 |
551 | UIImage *croppedImage = nil;
552 | orientationAfterProcess = orientationLast;
553 | switch (orientationLast) {
554 | case UIInterfaceOrientationPortrait:
555 | NSLog(@"UIInterfaceOrientationPortrait");
556 | croppedImage = [UIImage imageWithCGImage:imageRef];
557 | break;
558 |
559 | case UIInterfaceOrientationPortraitUpsideDown:
560 | NSLog(@"UIInterfaceOrientationPortraitUpsideDown");
561 | croppedImage = [[[UIImage alloc] initWithCGImage: imageRef
562 | scale: 1.0
563 | orientation: UIImageOrientationDown] autorelease];
564 | break;
565 |
566 | case UIInterfaceOrientationLandscapeLeft:
567 | NSLog(@"UIInterfaceOrientationLandscapeLeft");
568 | croppedImage = [[[UIImage alloc] initWithCGImage: imageRef
569 | scale: 1.0
570 | orientation: UIImageOrientationRight] autorelease];
571 | break;
572 |
573 | case UIInterfaceOrientationLandscapeRight:
574 | NSLog(@"UIInterfaceOrientationLandscapeRight");
575 | croppedImage = [[[UIImage alloc] initWithCGImage: imageRef
576 | scale: 1.0
577 | orientation: UIImageOrientationLeft] autorelease];
578 | break;
579 |
580 | default:
581 | croppedImage = [UIImage imageWithCGImage:imageRef];
582 | break;
583 | }
584 |
585 | CGImageRelease(imageRef);
586 |
587 | [self.captureImage setImage:croppedImage];
588 |
589 | [self setCapturedImage];
590 | }
591 |
592 | - (void)setCapturedImage{
593 | // Stop capturing image
594 | [session stopRunning];
595 |
596 | // Hide Top/Bottom controller after taking photo for editing
597 | [self hideControllers];
598 | }
599 |
600 | #pragma mark - Device Availability Controls
601 | - (void)disableCameraDeviceControls{
602 | self.cameraToggleButton.enabled = NO;
603 | self.flashToggleButton.enabled = NO;
604 | self.photoCaptureButton.enabled = NO;
605 | }
606 |
607 | //#pragma mark - UIImagePicker Delegate
608 | //- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
609 | // if (info) {
610 | // photoFromCam = NO;
611 | //
612 | // UIImage* outputImage = [info objectForKey:UIImagePickerControllerEditedImage];
613 | // if (outputImage == nil) {
614 | // outputImage = [info objectForKey:UIImagePickerControllerOriginalImage];
615 | // }
616 | //
617 | // if (outputImage) {
618 | // self.captureImage.hidden = NO;
619 | // self.captureImage.image=outputImage;
620 | //
621 | // [self dismissViewControllerAnimated:YES completion:nil];
622 | //
623 | // // Hide Top/Bottom controller after taking photo for editing
624 | // [self hideControllers];
625 | // }
626 | // }
627 | //}
628 |
629 | //- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
630 | // initializeCamera = YES;
631 | // [picker dismissViewControllerAnimated:YES completion:nil];
632 | //}
633 |
634 | #pragma mark - Button clicks
635 | - (IBAction)gridToogle:(UIButton *)sender{
636 | if (sender.selected) {
637 | sender.selected = NO;
638 | [UIView animateWithDuration:0.2 delay:0.0 options:0 animations:^{
639 | self.ImgViewGrid.alpha = 1.0f;
640 | } completion:nil];
641 | }
642 | else{
643 | sender.selected = YES;
644 | [UIView animateWithDuration:0.2 delay:0.0 options:0 animations:^{
645 | self.ImgViewGrid.alpha = 0.0f;
646 | } completion:nil];
647 | }
648 | }
649 |
650 | -(IBAction)switchToLibrary:(id)sender {
651 |
652 | if (session) {
653 | [session stopRunning];
654 | }
655 |
656 | // self.captureImage = nil;
657 |
658 | // UIImagePickerController* imagePickerController = [[UIImagePickerController alloc] init];
659 | // imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
660 | // imagePickerController.delegate = self;
661 | // imagePickerController.allowsEditing = YES;
662 | [self presentViewController:imgPicker animated:YES completion:NULL];
663 | }
664 |
665 | - (IBAction)skipped:(id)sender{
666 |
667 | if ([delegate respondsToSelector:@selector(yCameraControllerdidSkipped)]) {
668 | [delegate yCameraControllerdidSkipped];
669 | }
670 |
671 | // Dismiss self view controller
672 | [self dismissViewControllerAnimated:YES completion:nil];
673 | }
674 |
675 | -(IBAction) cancel:(id)sender {
676 | if ([delegate respondsToSelector:@selector(yCameraControllerDidCancel)]) {
677 | [delegate yCameraControllerDidCancel];
678 | }
679 |
680 | // Dismiss self view controller
681 | [self dismissViewControllerAnimated:YES completion:nil];
682 | }
683 |
684 | - (IBAction)donePhotoCapture:(id)sender{
685 | [session stopRunning];
686 | [motionManager stopDeviceMotionUpdates];
687 | imgPicker = Nil;
688 | session = Nil;
689 | motionManager = Nil;
690 | captureVideoPreviewLayer = Nil;
691 | stillImageOutput = Nil;
692 | if ([delegate respondsToSelector:@selector(didFinishPickingImage:metadata:)]) {
693 | [delegate didFinishPickingImage:self.captureImage.image metadata:metadata];
694 | }
695 | // Dismiss self view controller
696 | [self dismissViewControllerAnimated:NO completion:^(void)
697 | {
698 |
699 | }];
700 | }
701 |
702 | - (IBAction)retakePhoto:(id)sender{
703 | [self.photoCaptureButton setEnabled:YES];
704 | self.captureImage.image = nil;
705 | self.imagePreview.hidden = NO;
706 | // Show Camera device controls
707 | [self showControllers];
708 |
709 | haveImage=NO;
710 | FrontCamera = NO;
711 | // [self performSelector:@selector(initializeCamera) withObject:nil afterDelay:0.001];
712 | [session startRunning];
713 | }
714 |
715 | - (IBAction)switchCamera:(UIButton *)sender { //switch cameras front and rear cameras
716 | // Stop current recording process
717 | [session stopRunning];
718 |
719 | if (sender.selected) { // Switch to Back camera
720 | sender.selected = NO;
721 | FrontCamera = NO;
722 | [self performSelector:@selector(initializeCamera) withObject:nil afterDelay:0.001];
723 | }
724 | else { // Switch to Front camera
725 | sender.selected = YES;
726 | FrontCamera = YES;
727 | [self performSelector:@selector(initializeCamera) withObject:nil afterDelay:0.001];
728 | }
729 | }
730 |
731 | - (IBAction)toogleFlash:(UIButton *)sender{
732 | if (!FrontCamera) {
733 | if (sender.selected) { // Set flash off
734 | [sender setSelected:NO];
735 |
736 | NSArray *devices = [AVCaptureDevice devices];
737 | for (AVCaptureDevice *device in devices) {
738 | if ([device hasMediaType:AVMediaTypeVideo]) {
739 |
740 | if ([device position] == AVCaptureDevicePositionBack) {
741 | NSLog(@"Device position : back");
742 | if ([device hasFlash]){
743 |
744 | [device lockForConfiguration:nil];
745 | [device setFlashMode:AVCaptureFlashModeOff];
746 | [device unlockForConfiguration];
747 |
748 | break;
749 | }
750 | }
751 | }
752 | }
753 |
754 | }
755 | else{ // Set flash on
756 | [sender setSelected:YES];
757 |
758 | NSArray *devices = [AVCaptureDevice devices];
759 | for (AVCaptureDevice *device in devices) {
760 | if ([device hasMediaType:AVMediaTypeVideo]) {
761 |
762 | if ([device position] == AVCaptureDevicePositionBack) {
763 | NSLog(@"Device position : back");
764 | if ([device hasFlash]){
765 |
766 | [device lockForConfiguration:nil];
767 | [device setFlashMode:AVCaptureFlashModeOn];
768 | [device unlockForConfiguration];
769 |
770 | break;
771 | }
772 | }
773 | }
774 | }
775 |
776 | }
777 | }
778 | }
779 |
780 | #pragma mark - UI Control Helpers
781 | - (void)hideControllers{
782 | [UIView animateWithDuration:0.2 animations:^{
783 | //1)animate them out of screen
784 | self.photoBar.center = CGPointMake(self.photoBar.center.x, self.photoBar.center.y+116.0);
785 | self.topBar.center = CGPointMake(self.topBar.center.x, self.topBar.center.y-44.0);
786 |
787 | //2)actually hide them
788 | self.photoBar.alpha = 0.0;
789 | self.topBar.alpha = 0.0;
790 |
791 | } completion:nil];
792 | }
793 |
794 | - (void)showControllers{
795 | [UIView animateWithDuration:0.2 animations:^{
796 | //1)animate them into screen
797 | self.photoBar.center = CGPointMake(self.photoBar.center.x, self.photoBar.center.y-116.0);
798 | self.topBar.center = CGPointMake(self.topBar.center.x, self.topBar.center.y+44.0);
799 |
800 | //2)actually show them
801 | self.photoBar.alpha = 1.0;
802 | self.topBar.alpha = 1.0;
803 |
804 | } completion:nil];
805 | }
806 |
807 | @end
808 |
--------------------------------------------------------------------------------
/CustomImagePicker/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CustomImagePicker
4 | //
5 | // Created by C S P Nanda on 1/5/15.
6 | // Copyright (c) 2015 C S P Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/CustomImagePickerTests/CustomImagePickerTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // CustomImagePickerTests.m
3 | // CustomImagePickerTests
4 | //
5 | // Created by Prasanna Nanda on 1/5/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface CustomImagePickerTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation CustomImagePickerTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/CustomImagePickerTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | mompop.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Header.h
3 | // CustomImagePicker
4 | //
5 | // Created by Prasanna Nanda on 6/28/15.
6 | // Copyright (c) 2015 Prasanna Nanda. All rights reserved.
7 | //
8 |
9 | #ifndef CustomImagePicker_Header_h
10 | #define CustomImagePicker_Header_h
11 |
12 | #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
13 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
14 | #define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)
15 |
16 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
17 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
18 | #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
19 | #define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
20 |
21 | #define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
22 | #define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
23 | #define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
24 | #define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
25 |
26 |
27 |
28 | #define CELLCONTENTOFFSET 12.5
29 | #define MAX_ALLOWED_PICK 3
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 C S P Nanda
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CustomImagePicker
2 | An integrated Image Picker for iPhone like the one used in FB or twitter.
3 | All the images in your Camera Roll is shown as cells in a collection view.
4 | The Camera is shown as the first cell. Look at the attached screenshot.jpg.
5 | v2.0 adds the support for live camera feed. Read more about it at http://iosrecipe.blogspot.com/2015/06/integrated-image-picker-for-ios.html
6 |
7 | Branches
8 | --------
9 | 1. Master branch uses the ALAssetLibrary to handle photos.
10 | 2. photokit branch uses the PHAsset or the new Photo framework to handle photos. All new
11 | functionality will be available by Apple in the photokit going forward.
12 |
13 | How to Use it
14 | -------------
15 | 1. Add all files from the example project except the AppDelegate and
16 | ViewController to your project.
17 | 2. Import CustomImagePicker.h into your ViewController.h and implement the
18 | delegate CustomeImagePickerDelegate
19 | 3. Implement method -(void) imageSelected:(NSArray *)arrayOfImages in your
20 | ViewController to get the array containing AssetURLs.
21 |
--------------------------------------------------------------------------------
/images/camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/camera.png
--------------------------------------------------------------------------------
/images/cameraorange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/cameraorange.png
--------------------------------------------------------------------------------
/images/discard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/discard.png
--------------------------------------------------------------------------------
/images/discard@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/discard@2x.png
--------------------------------------------------------------------------------
/images/flash-auto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash-auto.png
--------------------------------------------------------------------------------
/images/flash-auto@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash-auto@2x.png
--------------------------------------------------------------------------------
/images/flash-off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash-off.png
--------------------------------------------------------------------------------
/images/flash-off@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash-off@2x.png
--------------------------------------------------------------------------------
/images/flash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash.png
--------------------------------------------------------------------------------
/images/flash@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/flash@2x.png
--------------------------------------------------------------------------------
/images/focus-crosshair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/focus-crosshair.png
--------------------------------------------------------------------------------
/images/focus-crosshair@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/focus-crosshair@2x.png
--------------------------------------------------------------------------------
/images/front-camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/front-camera.png
--------------------------------------------------------------------------------
/images/front-camera@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/front-camera@2x.png
--------------------------------------------------------------------------------
/images/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/screenshot.jpg
--------------------------------------------------------------------------------
/images/take-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/take-snap.png
--------------------------------------------------------------------------------
/images/take-snap@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/take-snap@2x.png
--------------------------------------------------------------------------------
/images/tick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/images/tick.png
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cspnanda/CustomImagePicker/72f140b66a91e8f09506e29912cf1e4c76119479/screenshot.jpg
--------------------------------------------------------------------------------