├── .gitignore ├── BTL Utilities ├── BTLFullScreenCameraController.h ├── BTLFullScreenCameraController.m ├── BTLImageShareController.h └── BTLImageShareController.m ├── Classes ├── Example.h ├── Example.m ├── HelpfulUtilitiesAppDelegate.h ├── HelpfulUtilitiesAppDelegate.m ├── RootViewController.h └── RootViewController.m ├── Examples ├── FullScreenCameraExampleController.h └── FullScreenCameraExampleController.m ├── HelpfulUtilities-Info.plist ├── HelpfulUtilities.xcodeproj └── project.pbxproj ├── HelpfulUtilities_Prefix.pch ├── Other Utilities ├── MBProgressHUD.h └── MBProgressHUD.m ├── Views ├── MainWindow.xib └── RootViewController.xib ├── binocs.png ├── llamas.jpg ├── main.m └── overlay1.png /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.xcodeproj/*.mode1v3 3 | *.xcodeproj/*.mode2v3 4 | *.xcodeproj/*.pbxuser 5 | *.xcodeproj/*.perspectivev3 6 | *.swp 7 | *~.nib 8 | .DS_Store 9 | 10 | */errorLogFromLastBuild.txt 11 | -------------------------------------------------------------------------------- /BTL Utilities/BTLFullScreenCameraController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTLFullScreenCameraController.h 3 | // 4 | // Created by P. Mark Anderson on 8/6/2009. 5 | // Copyright (c) 2009 Bordertown Labs, LLC. 6 | // 7 | // Permission is hereby granted, free of charge, to any person 8 | // obtaining a copy of this software and associated documentation 9 | // files (the "Software"), to deal in the Software without 10 | // restriction, including without limitation the rights to use, 11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the 13 | // Software is furnished to do so, subject to the following 14 | // conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be 17 | // included in all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | // See HelpfulUtilities_Prefix.pch 32 | #ifdef BTL_INCLUDE_IMAGE_SHARING 33 | #import "BTLImageShareController.h" 34 | #endif 35 | 36 | 37 | @interface BTLFullScreenCameraController : UIImagePickerController { 38 | UIViewController *overlayController; 39 | UILabel *statusLabel; 40 | UIImageView *shadeOverlay; 41 | 42 | #ifdef BTL_INCLUDE_IMAGE_SHARING 43 | BTLImageShareController *shareController; 44 | #endif 45 | 46 | } 47 | 48 | @property (nonatomic, retain) UIViewController *overlayController; 49 | @property (nonatomic, retain) UILabel *statusLabel; 50 | @property (nonatomic, retain) UIImageView *shadeOverlay; 51 | 52 | #ifdef BTL_INCLUDE_IMAGE_SHARING 53 | @property (nonatomic, retain) BTLImageShareController *shareController; 54 | #endif 55 | 56 | + (BOOL)isAvailable; 57 | - (void)displayModalWithController:(UIViewController*)controller animated:(BOOL)animated; 58 | - (void)dismissModalViewControllerAnimated:(BOOL)animated; 59 | - (void)takePicture; 60 | - (void)writeImageToDocuments:(UIImage*)image; 61 | - (void)initStatusMessage; 62 | - (void)showStatusMessage:(NSString*)message; 63 | - (void)hideStatusMessage; 64 | - (void)showShadeOverlay; 65 | - (void)hideShadeOverlay; 66 | - (void)animateShadeOverlay:(CGFloat)alpha; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /BTL Utilities/BTLFullScreenCameraController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTLFullScreenCameraController.m 3 | // 4 | // Created by P. Mark Anderson on 8/6/2009. 5 | // Copyright (c) 2009 Bordertown Labs, LLC. 6 | // 7 | // Permission is hereby granted, free of charge, to any person 8 | // obtaining a copy of this software and associated documentation 9 | // files (the "Software"), to deal in the Software without 10 | // restriction, including without limitation the rights to use, 11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the 13 | // Software is furnished to do so, subject to the following 14 | // conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be 17 | // included in all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #import "BTLFullScreenCameraController.h" 30 | #include 31 | 32 | #define CAMERA_SCALAR 1.12412 // scalar = (480 / (2048 / 480)) 33 | 34 | @implementation BTLFullScreenCameraController 35 | 36 | @synthesize statusLabel, shadeOverlay, overlayController; 37 | 38 | #ifdef BTL_INCLUDE_IMAGE_SHARING 39 | @synthesize shareController; 40 | #endif 41 | 42 | - (id)init { 43 | if (self = [super init]) { 44 | self.sourceType = UIImagePickerControllerSourceTypeCamera; 45 | self.showsCameraControls = NO; 46 | self.navigationBarHidden = YES; 47 | self.toolbarHidden = YES; 48 | self.wantsFullScreenLayout = YES; 49 | self.cameraViewTransform = CGAffineTransformScale(self.cameraViewTransform, CAMERA_SCALAR, CAMERA_SCALAR); 50 | 51 | if ([self.overlayController respondsToSelector:@selector(initStatusMessage)]) { 52 | [self.overlayController performSelector:@selector(initStatusMessage)]; 53 | } else { 54 | [self initStatusMessage]; 55 | } 56 | } 57 | return self; 58 | } 59 | 60 | 61 | - (void)viewDidAppear:(BOOL)animated { 62 | [super viewDidAppear:animated]; 63 | self.shadeOverlay = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"overlay1.png"]] autorelease]; 64 | self.shadeOverlay.alpha = 0.0f; 65 | [self.view addSubview:self.shadeOverlay]; 66 | } 67 | 68 | 69 | + (BOOL)isAvailable { 70 | return [self isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]; 71 | } 72 | 73 | - (void)displayModalWithController:(UIViewController*)controller animated:(BOOL)animated { 74 | [controller presentModalViewController:self animated:YES]; 75 | } 76 | 77 | - (void)dismissModalViewControllerAnimated:(BOOL)animated { 78 | [self.overlayController dismissModalViewControllerAnimated:animated]; 79 | } 80 | 81 | - (void)takePicture { 82 | if ([self.overlayController respondsToSelector:@selector(cameraWillTakePicture:)]) { 83 | [self.overlayController performSelector:@selector(cameraWillTakePicture:) withObject:self]; 84 | } 85 | 86 | self.delegate = self; 87 | [self showStatusMessage:@"Taking photo..."]; 88 | 89 | #ifdef BTL_INCLUDE_IMAGE_SHARING 90 | if (self.shareController) { 91 | [self.shareController hideThumbnail]; 92 | } 93 | #endif 94 | 95 | [self showShadeOverlay]; 96 | [super takePicture]; 97 | } 98 | 99 | - (UIImage*)dumpOverlayViewToImage { 100 | CGSize imageSize = self.cameraOverlayView.bounds.size; 101 | UIGraphicsBeginImageContext(imageSize); 102 | [self.cameraOverlayView.layer renderInContext:UIGraphicsGetCurrentContext()]; 103 | UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 104 | UIGraphicsEndImageContext(); 105 | 106 | return viewImage; 107 | } 108 | 109 | - (UIImage*)addOverlayToBaseImage:(UIImage*)baseImage { 110 | UIImage *overlayImage = [self dumpOverlayViewToImage]; 111 | CGPoint topCorner = CGPointMake(0, 0); 112 | CGSize targetSize = CGSizeMake(320, 480); 113 | CGRect scaledRect = CGRectZero; 114 | 115 | CGFloat scaledX = 480 * baseImage.size.width / baseImage.size.height; 116 | CGFloat offsetX = (scaledX - 320) / -2; 117 | 118 | scaledRect.origin = CGPointMake(offsetX, 0.0); 119 | scaledRect.size.width = scaledX; 120 | scaledRect.size.height = 480; 121 | 122 | UIGraphicsBeginImageContext(targetSize); 123 | [baseImage drawInRect:scaledRect]; 124 | [overlayImage drawAtPoint:topCorner]; 125 | UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); 126 | UIGraphicsEndImageContext(); 127 | 128 | return result; 129 | } 130 | 131 | - (void)adjustLandscapePhoto:(UIImage*)image { 132 | // TODO: maybe use this for something 133 | NSLog(@"camera image: %f x %f", image.size.width, image.size.height); 134 | 135 | switch (image.imageOrientation) { 136 | case UIImageOrientationLeft: 137 | case UIImageOrientationRight: 138 | // portrait 139 | NSLog(@"portrait"); 140 | break; 141 | default: 142 | // landscape 143 | NSLog(@"landscape"); 144 | break; 145 | } 146 | } 147 | 148 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 149 | [self showStatusMessage:@"Saving photo..."]; 150 | UIImage *baseImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 151 | if (baseImage == nil) return; 152 | 153 | // save composite 154 | UIImage *compositeImage = [self addOverlayToBaseImage:baseImage]; 155 | [self hideStatusMessage]; 156 | [self hideShadeOverlay]; 157 | 158 | if ([self.overlayController respondsToSelector:@selector(cameraDidTakePicture:)]) { 159 | [self.overlayController performSelector:@selector(cameraDidTakePicture:) withObject:self]; 160 | } 161 | 162 | UIImageWriteToSavedPhotosAlbum(compositeImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 163 | 164 | #ifdef BTL_INCLUDE_IMAGE_SHARING 165 | // thumbnail 166 | if (self.shareController) { 167 | [self.shareController generateAndShowThumbnail:compositeImage]; 168 | [self.shareController hideThumbnailAfterDelay:5.0f]; 169 | } 170 | #endif 171 | 172 | } 173 | 174 | - (void)image:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo:(NSDictionary*)info { 175 | } 176 | 177 | - (void)initStatusMessage { 178 | self.statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, self.view.bounds.size.height)]; 179 | self.statusLabel.textAlignment = UITextAlignmentCenter; 180 | self.statusLabel.adjustsFontSizeToFitWidth = YES; 181 | self.statusLabel.backgroundColor = [UIColor clearColor]; 182 | self.statusLabel.textColor = [UIColor whiteColor]; 183 | self.statusLabel.shadowOffset = CGSizeMake(0, -1); 184 | self.statusLabel.shadowColor = [UIColor blackColor]; 185 | self.statusLabel.hidden = YES; 186 | [self.view addSubview:self.statusLabel]; 187 | } 188 | 189 | - (void)showStatusMessage:(NSString*)message { 190 | if ([self.overlayController respondsToSelector:@selector(showStatusMessage:)]) { 191 | [self.overlayController performSelector:@selector(showStatusMessage) withObject:message]; 192 | } else { 193 | self.statusLabel.text = message; 194 | self.statusLabel.hidden = NO; 195 | [self.view bringSubviewToFront:self.statusLabel]; 196 | } 197 | } 198 | 199 | - (void)hideStatusMessage { 200 | if ([self.overlayController respondsToSelector:@selector(hideStatusMessage)]) { 201 | [self.overlayController performSelector:@selector(hideStatusMessage)]; 202 | } else { 203 | self.statusLabel.hidden = YES; 204 | } 205 | } 206 | 207 | - (void)showShadeOverlay { 208 | [self animateShadeOverlay:0.82f]; 209 | } 210 | 211 | - (void)hideShadeOverlay { 212 | [self animateShadeOverlay:0.0f]; 213 | } 214 | 215 | - (void)animateShadeOverlay:(CGFloat)alpha { 216 | [UIView beginAnimations:nil context:nil]; 217 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 218 | [UIView setAnimationDuration:0.35f]; 219 | self.shadeOverlay.alpha = alpha; 220 | [UIView commitAnimations]; 221 | } 222 | 223 | - (void)writeImageToDocuments:(UIImage*)image { 224 | NSData *png = UIImagePNGRepresentation(image); 225 | 226 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 227 | NSString *documentsDirectory = [paths objectAtIndex:0]; 228 | 229 | NSError *error = nil; 230 | [png writeToFile:[documentsDirectory stringByAppendingPathComponent:@"image.png"] options:NSAtomicWrite error:&error]; 231 | } 232 | 233 | - (BOOL)canBecomeFirstResponder { return YES; } 234 | 235 | - (void)dealloc { 236 | [overlayController release]; 237 | [statusLabel release]; 238 | [shadeOverlay release]; 239 | 240 | #ifdef BTL_INCLUDE_IMAGE_SHARING 241 | [shareController release]; 242 | #endif 243 | [super dealloc]; 244 | 245 | } 246 | 247 | 248 | @end 249 | -------------------------------------------------------------------------------- /BTL Utilities/BTLImageShareController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BTLImageShareController.h 3 | // 4 | // Created by P. Mark Anderson on 9/22/09. 5 | // Copyright (c) 2009 Bordertown Labs, LLC. 6 | // 7 | // Permission is hereby granted, free of charge, to any person 8 | // obtaining a copy of this software and associated documentation 9 | // files (the "Software"), to deal in the Software without 10 | // restriction, including without limitation the rights to use, 11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the 13 | // Software is furnished to do so, subject to the following 14 | // conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be 17 | // included in all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #ifdef BTL_INCLUDE_IMAGE_SHARING 30 | 31 | #import 32 | #import 33 | #import 34 | 35 | @interface BTLImageShareController : UIViewController { 36 | UIImage *image; 37 | UIButton *imageButton; 38 | UIButton *thumbnailButton; 39 | id delegate; 40 | } 41 | 42 | @property (nonatomic,retain) UIImage *image; 43 | @property (nonatomic,assign) id delegate; 44 | 45 | - (void)hideThumbnail; 46 | - (void)hideThumbnailAfterDelay:(CGFloat)delay; 47 | - (void)showThumbnail:(UIImage *)newImage; 48 | - (UIImage*)generateThumbnail:(UIImage*)source; 49 | - (void)generateAndShowThumbnail:(UIImage*)source; 50 | - (void)hidePreviewImage; 51 | - (void)emailPhoto; 52 | 53 | @end 54 | #endif -------------------------------------------------------------------------------- /BTL Utilities/BTLImageShareController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BTLImageShareController.m 3 | // 4 | // Created by P. Mark Anderson on 9/22/09. 5 | // Copyright (c) 2009 Bordertown Labs, LLC. 6 | // 7 | // Permission is hereby granted, free of charge, to any person 8 | // obtaining a copy of this software and associated documentation 9 | // files (the "Software"), to deal in the Software without 10 | // restriction, including without limitation the rights to use, 11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the 13 | // Software is furnished to do so, subject to the following 14 | // conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be 17 | // included in all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | // OTHER DEALINGS IN THE SOFTWARE. 27 | // 28 | 29 | #ifdef BTL_INCLUDE_IMAGE_SHARING 30 | 31 | #import "BTLImageShareController.h" 32 | #import 33 | 34 | #define THUMBNAIL_WIDTH 50 35 | #define THUMBNAIL_HEIGHT 75 36 | #define THUMBNAIL_FRAME_WIDTH 50 37 | #define THUMBNAIL_FRAME_HEIGHT 75 38 | #define THUMBNAIL_FRAME_OFFSET_X 0 39 | #define THUMBNAIL_FRAME_OFFSET_Y 0 40 | 41 | @implementation BTLImageShareController 42 | 43 | @synthesize image, delegate; 44 | 45 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 46 | - (void)viewDidLoad { 47 | [super viewDidLoad]; 48 | 49 | thumbnailButton = [UIButton buttonWithType:UIButtonTypeCustom]; 50 | thumbnailButton.frame = CGRectMake(self.view.frame.size.width - THUMBNAIL_FRAME_WIDTH - 10, 51 | self.view.frame.size.height - THUMBNAIL_FRAME_HEIGHT - 10, 52 | THUMBNAIL_FRAME_WIDTH, THUMBNAIL_FRAME_HEIGHT); 53 | [thumbnailButton addTarget:self action:@selector(thumbnailTapped:) forControlEvents:UIControlEventTouchUpInside]; 54 | thumbnailButton.hidden = YES; 55 | [self.view addSubview:thumbnailButton]; 56 | 57 | imageButton = [UIButton buttonWithType:UIButtonTypeCustom]; 58 | imageButton.frame = CGRectMake(0, 0, 320, 480); 59 | [imageButton addTarget:self action:@selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside]; 60 | imageButton.hidden = NO; 61 | imageButton.alpha = 0.0f; 62 | [self.view addSubview:imageButton]; 63 | } 64 | 65 | - (void)thumbnailTapped:(id)sender { 66 | if ([self.delegate respondsToSelector:@selector(thumbnailTapped:)]) { 67 | [self.delegate thumbnailTapped:self]; 68 | } 69 | 70 | [self hideThumbnail]; 71 | 72 | // fade in full screen image 73 | [UIView beginAnimations:nil context:nil]; 74 | [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 75 | [UIView setAnimationDuration:0.66f]; 76 | imageButton.alpha = 1.0f; 77 | [UIView commitAnimations]; 78 | 79 | [self.view bringSubviewToFront:imageButton]; 80 | } 81 | 82 | - (void)imageTapped:(id)sender { 83 | UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle: nil 84 | delegate: self 85 | cancelButtonTitle: @"Cancel" 86 | destructiveButtonTitle: NULL 87 | otherButtonTitles: @"Email Photo", @"Go Back", NULL]; 88 | actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent; 89 | [actionSheet showInView:self.view]; 90 | [actionSheet release]; 91 | } 92 | 93 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { 94 | switch (buttonIndex) { 95 | case 0: 96 | [self emailPhoto]; 97 | break; 98 | case 1: 99 | [self hidePreviewImage]; 100 | if ([self.delegate respondsToSelector:@selector(previewClosed:)]) { 101 | [self.delegate performSelector:@selector(previewClosed:) withObject:self]; 102 | } 103 | break; 104 | default: 105 | break; 106 | } 107 | } 108 | 109 | - (void)emailPhoto { 110 | if (![MFMailComposeViewController canSendMail]) { 111 | UIAlertView *cantMailAlert = [[UIAlertView alloc] initWithTitle:@"Uh oh..." 112 | message:@"Sorry, this device is not able to send e-mail" delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:NULL]; 113 | [cantMailAlert show]; 114 | [cantMailAlert release]; 115 | return; 116 | } 117 | 118 | MFMailComposeViewController *mailController = [[[MFMailComposeViewController alloc] init] autorelease]; 119 | 120 | NSData *imageData = UIImageJPEGRepresentation(self.image, 1.0); 121 | [mailController addAttachmentData:imageData mimeType:@"image/jpg" fileName:@"image"]; 122 | 123 | NSString *emailBody = @""; 124 | NSString *emailSubject = @""; 125 | [mailController setMessageBody:emailBody isHTML:NO]; 126 | [mailController setSubject:emailSubject]; 127 | mailController.mailComposeDelegate = self; 128 | [self presentModalViewController:mailController animated:YES]; 129 | } 130 | 131 | - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { 132 | [self becomeFirstResponder]; 133 | [self dismissModalViewControllerAnimated:YES]; 134 | } 135 | 136 | - (void)hidePreviewImage { 137 | [UIView beginAnimations:nil context:nil]; 138 | [UIView setAnimationCurve:UIViewAnimationCurveEaseOut]; 139 | [UIView setAnimationDuration:0.66f]; 140 | imageButton.alpha = 0.0f; 141 | [UIView commitAnimations]; 142 | } 143 | 144 | - (UIImage*)generateThumbnail:(UIImage*)source { 145 | CGRect scaledRect = CGRectZero; 146 | scaledRect.size.width = THUMBNAIL_WIDTH; 147 | scaledRect.size.height = THUMBNAIL_HEIGHT; 148 | scaledRect.origin = CGPointMake(THUMBNAIL_FRAME_OFFSET_X, THUMBNAIL_FRAME_OFFSET_Y); 149 | CGSize targetSize = CGSizeMake(THUMBNAIL_FRAME_WIDTH, THUMBNAIL_FRAME_HEIGHT); 150 | 151 | UIGraphicsBeginImageContext(targetSize); 152 | [source drawInRect:scaledRect]; 153 | 154 | // draw a simple thumbnail border 155 | CGContextRef context = UIGraphicsGetCurrentContext(); 156 | CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.07f); 157 | CGContextStrokeRectWithWidth(context, scaledRect, 5.0f); 158 | 159 | UIImage* thumbnailImage = UIGraphicsGetImageFromCurrentImageContext(); 160 | UIGraphicsEndImageContext(); 161 | return thumbnailImage; 162 | } 163 | 164 | - (void)showThumbnail:(UIImage *)newImage { 165 | [thumbnailButton setImage:newImage forState:UIControlStateNormal]; 166 | thumbnailButton.alpha = 0.0f; 167 | thumbnailButton.hidden = NO; 168 | 169 | CGAffineTransform preTransform = CGAffineTransformMakeScale(0.1f, 0.1f); 170 | thumbnailButton.transform = preTransform; 171 | 172 | [UIView beginAnimations:nil context:nil]; 173 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 174 | 175 | [UIView setAnimationDuration:0.3f]; 176 | thumbnailButton.alpha = 1.0f; 177 | 178 | CGAffineTransform transform = CGAffineTransformMakeScale(1.0f, 1.0f); 179 | thumbnailButton.transform = transform; 180 | 181 | [UIView commitAnimations]; 182 | } 183 | 184 | - (void)generateAndShowThumbnail:(UIImage*)newImage { 185 | if (newImage != nil && newImage != self.image) { 186 | self.image = newImage; 187 | [imageButton setImage:newImage forState:UIControlStateNormal]; 188 | } 189 | 190 | UIImage *thumb = [self generateThumbnail:self.image]; 191 | [self showThumbnail:thumb]; 192 | } 193 | 194 | - (void)hideThumbnail { 195 | if (thumbnailButton.hidden || thumbnailButton.alpha == 0.0f) return; 196 | 197 | [UIView beginAnimations:nil context:nil]; 198 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 199 | 200 | [UIView setAnimationDuration:0.3f]; 201 | thumbnailButton.alpha = 0.0f; 202 | 203 | CGAffineTransform transform = CGAffineTransformMakeScale(0.01f, 0.01f); 204 | thumbnailButton.transform = transform; 205 | 206 | [UIView commitAnimations]; 207 | } 208 | 209 | - (void)hideThumbnailAfterDelay:(CGFloat)delay { 210 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 211 | [self performSelector:@selector(hideThumbnail) withObject:self afterDelay:delay]; 212 | } 213 | 214 | - (void)didReceiveMemoryWarning { 215 | // Releases the view if it doesn't have a superview. 216 | [super didReceiveMemoryWarning]; 217 | 218 | // Release any cached data, images, etc that aren't in use. 219 | } 220 | 221 | - (void)viewDidUnload { 222 | // Release any retained subviews of the main view. 223 | // e.g. self.myOutlet = nil; 224 | } 225 | 226 | 227 | - (void)dealloc { 228 | [image release]; 229 | [imageButton release]; 230 | [thumbnailButton release]; 231 | [delegate release]; 232 | [super dealloc]; 233 | } 234 | 235 | 236 | @end 237 | #endif -------------------------------------------------------------------------------- /Classes/Example.h: -------------------------------------------------------------------------------- 1 | // 2 | // Example.h 3 | // ExampleEditor 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | // 9 | // Licensed with the Apache 2.0 License 10 | // http://apache.org/licenses/LICENSE-2.0 11 | // 12 | 13 | 14 | @interface Example : NSObject { 15 | NSString *title; 16 | NSString *controllerClass; 17 | } 18 | 19 | - (id)initWithTitle:(NSString *)newTitle 20 | controllerClass:(NSString *)newControllerClass; 21 | 22 | @property(nonatomic, copy) NSString *title; 23 | @property(nonatomic, copy) NSString *controllerClass; 24 | 25 | @end -------------------------------------------------------------------------------- /Classes/Example.m: -------------------------------------------------------------------------------- 1 | // 2 | // Example.m 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | // Licensed with the Apache 2.0 License 9 | // http://apache.org/licenses/LICENSE-2.0 10 | // 11 | 12 | 13 | #import "Example.h" 14 | 15 | @implementation Example 16 | 17 | @synthesize title, controllerClass; 18 | 19 | - (id)initWithTitle:(NSString *)newTitle 20 | controllerClass:(NSString *)newControllerClass { 21 | self = [super init]; 22 | if(nil != self) { 23 | self.title = newTitle; 24 | self.controllerClass = newControllerClass; 25 | } 26 | return self; 27 | } 28 | 29 | - (void) dealloc { 30 | self.title = nil; 31 | self.controllerClass = nil; 32 | [super dealloc]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Classes/HelpfulUtilitiesAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // HelpfulUtilitiesAppDelegate.h 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | @interface HelpfulUtilitiesAppDelegate : NSObject { 10 | 11 | UIWindow *window; 12 | UINavigationController *navigationController; 13 | } 14 | 15 | @property (nonatomic, retain) IBOutlet UIWindow *window; 16 | @property (nonatomic, retain) IBOutlet UINavigationController *navigationController; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /Classes/HelpfulUtilitiesAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // HelpfulUtilitiesAppDelegate.m 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | #import "HelpfulUtilitiesAppDelegate.h" 10 | #import "RootViewController.h" 11 | 12 | 13 | @implementation HelpfulUtilitiesAppDelegate 14 | 15 | @synthesize window; 16 | @synthesize navigationController; 17 | 18 | 19 | #pragma mark - 20 | #pragma mark Application lifecycle 21 | 22 | - (void)applicationDidFinishLaunching:(UIApplication *)application { 23 | 24 | // Override point for customization after app launch 25 | [window addSubview:[navigationController view]]; 26 | [window makeKeyAndVisible]; 27 | } 28 | 29 | 30 | - (void)applicationWillTerminate:(UIApplication *)application { 31 | // Save data if appropriate 32 | } 33 | 34 | 35 | #pragma mark - 36 | #pragma mark Memory management 37 | 38 | - (void)dealloc { 39 | [navigationController release]; 40 | [window release]; 41 | [super dealloc]; 42 | } 43 | 44 | 45 | @end 46 | 47 | -------------------------------------------------------------------------------- /Classes/RootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.h 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | @interface RootViewController : UITableViewController { 10 | NSMutableArray *examplesArray; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/RootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.m 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | #import "RootViewController.h" 10 | #import "Example.h" 11 | #import "FullScreenCameraExampleController.h" 12 | 13 | 14 | NSString *testExampleData[][2] = { 15 | {@"FullScreenCamera", @"FullScreenCameraExampleController"}, 16 | }; 17 | 18 | @implementation RootViewController 19 | 20 | -(void) loadTestData { 21 | // fill examplesArray with test data 22 | for (int i=0; i<1; i++) { 23 | Example *anExample = [[Example alloc] init]; 24 | anExample.title = testExampleData[i][0]; 25 | anExample.controllerClass = testExampleData[i][1]; 26 | [examplesArray addObject: anExample]; 27 | [anExample release]; 28 | } 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | examplesArray = [[NSMutableArray alloc] init]; 34 | [self loadTestData]; 35 | } 36 | 37 | /* 38 | - (void)viewDidLoad { 39 | [super viewDidLoad]; 40 | 41 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 42 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 43 | } 44 | */ 45 | 46 | /* 47 | - (void)viewWillAppear:(BOOL)animated { 48 | [super viewWillAppear:animated]; 49 | } 50 | */ 51 | /* 52 | - (void)viewDidAppear:(BOOL)animated { 53 | [super viewDidAppear:animated]; 54 | } 55 | */ 56 | /* 57 | - (void)viewWillDisappear:(BOOL)animated { 58 | [super viewWillDisappear:animated]; 59 | } 60 | */ 61 | /* 62 | - (void)viewDidDisappear:(BOOL)animated { 63 | [super viewDidDisappear:animated]; 64 | } 65 | */ 66 | 67 | /* 68 | // Override to allow orientations other than the default portrait orientation. 69 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 70 | // Return YES for supported orientations. 71 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 72 | } 73 | */ 74 | 75 | - (void)didReceiveMemoryWarning { 76 | // Releases the view if it doesn't have a superview. 77 | [super didReceiveMemoryWarning]; 78 | 79 | // Release any cached data, images, etc that aren't in use. 80 | } 81 | 82 | - (void)viewDidUnload { 83 | // Release anything that can be recreated in viewDidLoad or on demand. 84 | // e.g. self.myOutlet = nil; 85 | } 86 | 87 | 88 | #pragma mark Table view methods 89 | 90 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 91 | return 1; 92 | } 93 | 94 | 95 | // Customize the number of rows in the table view. 96 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 97 | return [examplesArray count]; 98 | } 99 | 100 | 101 | // Customize the appearance of table view cells. 102 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 103 | static NSString *CellIdentifier = @"Cell"; 104 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 105 | if (cell == nil) { 106 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 107 | reuseIdentifier:CellIdentifier] autorelease]; 108 | } 109 | 110 | Example *anExample = [examplesArray objectAtIndex:indexPath.row]; 111 | cell.textLabel.text = anExample.title; 112 | return cell; 113 | } 114 | 115 | 116 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 117 | Example *example = [examplesArray objectAtIndex:indexPath.row]; 118 | UIViewController *exampleController = [[NSClassFromString(example.controllerClass) alloc] init]; 119 | 120 | [self.navigationController pushViewController:exampleController animated:YES]; 121 | } 122 | 123 | 124 | 125 | /* 126 | // Override to support row selection in the table view. 127 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 128 | 129 | // Navigation logic may go here -- for example, create and push another view controller. 130 | // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; 131 | // [self.navigationController pushViewController:anotherViewController animated:YES]; 132 | // [anotherViewController release]; 133 | } 134 | */ 135 | 136 | 137 | /* 138 | // Override to support conditional editing of the table view. 139 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 140 | // Return NO if you do not want the specified item to be editable. 141 | return YES; 142 | } 143 | */ 144 | 145 | 146 | /* 147 | // Override to support editing the table view. 148 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 149 | 150 | if (editingStyle == UITableViewCellEditingStyleDelete) { 151 | // Delete the row from the data source. 152 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 153 | } 154 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 155 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. 156 | } 157 | } 158 | */ 159 | 160 | 161 | /* 162 | // Override to support rearranging the table view. 163 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 164 | } 165 | */ 166 | 167 | 168 | /* 169 | // Override to support conditional rearranging of the table view. 170 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 171 | // Return NO if you do not want the item to be re-orderable. 172 | return YES; 173 | } 174 | */ 175 | 176 | 177 | - (void)dealloc { 178 | [super dealloc]; 179 | } 180 | 181 | 182 | @end 183 | 184 | -------------------------------------------------------------------------------- /Examples/FullScreenCameraExampleController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FullScreenCameraExampleController.h 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BTLFullScreenCameraController.h" 11 | #import "MBProgressHUD.h" 12 | 13 | 14 | @interface FullScreenCameraExampleController : UIViewController { 15 | BTLFullScreenCameraController *camera; 16 | UIView *overlayView; 17 | BOOL cameraMode; 18 | CGPoint startTouchPosition; 19 | UILabel *overlayLabel; 20 | } 21 | 22 | @property (nonatomic, retain) BTLFullScreenCameraController *camera; 23 | @property (nonatomic, retain) UIView *overlayView; 24 | @property (nonatomic, retain) UILabel *overlayLabel; 25 | @property (assign) BOOL cameraMode; 26 | @property (nonatomic) CGPoint startTouchPosition; 27 | 28 | - (void)initCamera; 29 | - (void)toggleAugmentedReality; 30 | - (void)startCamera; 31 | - (void)onSingleTap:(UITouch*)touch; 32 | - (void)onDoubleTap:(UITouch*)touch; 33 | - (void)onSwipeUp; 34 | - (void)onSwipeDown; 35 | - (void)onSwipeLeft; 36 | - (void)onSwipeRight; 37 | - (void)cameraWillTakePicture:(id)sender; 38 | - (void)cameraDidTakePicture:(id)sender; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Examples/FullScreenCameraExampleController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FullScreenCameraExampleController.m 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | #import "FullScreenCameraExampleController.h" 10 | 11 | #ifdef BTL_INCLUDE_IMAGE_SHARING 12 | #import "BTLImageShareController.h" 13 | #endif 14 | 15 | // horizontal onSwipe 16 | #define HORIZ_SWIPE_DRAG_MIN 180 17 | #define VERT_SWIPE_DRAG_MAX 100 18 | 19 | // vertical onSwipe 20 | #define HORIZ_SWIPE_DRAG_MAX 100 21 | #define VERT_SWIPE_DRAG_MIN 250 22 | 23 | #define OVERLAY_ALPHA 0.90f 24 | #define BINOCS_TAG 99 25 | #define BINOCS_BUTTON_TAG 100 26 | 27 | @implementation FullScreenCameraExampleController 28 | 29 | @synthesize camera, cameraMode, overlayView, overlayLabel, startTouchPosition; 30 | 31 | 32 | - (void)loadView { 33 | self.navigationController.toolbarHidden = YES; 34 | self.navigationController.navigationBarHidden = YES; 35 | [UIApplication sharedApplication].statusBarHidden = YES; 36 | 37 | self.overlayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; 38 | self.overlayView.opaque = NO; 39 | self.overlayView.alpha = OVERLAY_ALPHA; 40 | 41 | UIImageView *binocs = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"binocs.png"]] autorelease]; 42 | binocs.tag = BINOCS_TAG; 43 | [self.overlayView addSubview:binocs]; 44 | 45 | self.overlayLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 40)]; 46 | self.overlayLabel.text = @"Starting camera..."; 47 | self.overlayLabel.textAlignment = UITextAlignmentCenter; 48 | self.overlayLabel.adjustsFontSizeToFitWidth = YES; 49 | self.overlayLabel.textColor = [UIColor redColor]; 50 | self.overlayLabel.backgroundColor = [UIColor darkGrayColor]; 51 | self.overlayLabel.shadowOffset = CGSizeMake(0, -1); 52 | self.overlayLabel.shadowColor = [UIColor blackColor]; 53 | [self.overlayView addSubview:self.overlayLabel]; 54 | 55 | self.view = self.overlayView; 56 | } 57 | 58 | - (void) viewDidAppear:(BOOL)animated { 59 | [self initCamera]; 60 | [self startCamera]; 61 | self.overlayLabel.text = @"Tap to take a picture."; 62 | 63 | UIButton *binocsButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain]; 64 | binocsButton.tag = BINOCS_BUTTON_TAG; 65 | [binocsButton setTitle:@"Binocs" forState:UIControlStateNormal]; 66 | binocsButton.backgroundColor = [UIColor clearColor]; 67 | binocsButton.frame = CGRectMake(10, 426, 100, 44); 68 | [binocsButton addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 69 | [self.overlayView addSubview:binocsButton]; 70 | } 71 | 72 | - (void) initCamera { 73 | if ([BTLFullScreenCameraController isAvailable]) { 74 | 75 | NSLog(@"Initializing camera."); 76 | BTLFullScreenCameraController *tmpCamera = [[BTLFullScreenCameraController alloc] init]; 77 | [tmpCamera.view setBackgroundColor:[UIColor blueColor]]; 78 | [tmpCamera setCameraOverlayView:self.overlayView]; 79 | tmpCamera.overlayController = self; 80 | 81 | #ifdef BTL_INCLUDE_IMAGE_SHARING 82 | BTLImageShareController *shareController = [[BTLImageShareController alloc] init]; 83 | shareController.delegate = self; 84 | [self.view addSubview:shareController.view]; 85 | tmpCamera.shareController = shareController; 86 | #endif 87 | 88 | self.camera = tmpCamera; 89 | [tmpCamera release]; 90 | } else { 91 | NSLog(@"Camera not available."); 92 | } 93 | } 94 | 95 | - (void)startCamera { 96 | // TODO: figure out why simply setting the view is not working 97 | // since the modal view is not as desirable 98 | 99 | // This isn't working but should: 100 | //self.view = self.camera.view; 101 | 102 | // Modal view always works, but it's harder to work with. 103 | [self.camera displayModalWithController:self animated:YES]; 104 | } 105 | 106 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 107 | // if landscape, put in camera mode 108 | switch (interfaceOrientation) { 109 | case UIInterfaceOrientationLandscapeLeft: 110 | case UIInterfaceOrientationLandscapeRight: 111 | [self toggleAugmentedReality]; 112 | break; 113 | } 114 | 115 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 116 | } 117 | 118 | -(void)toggleAugmentedReality { 119 | if ([BTLFullScreenCameraController isAvailable]) { 120 | self.cameraMode = !self.cameraMode; 121 | if (self.cameraMode == YES) { 122 | NSLog(@"Setting view to camera"); 123 | if (!self.camera) { [self initCamera]; } 124 | 125 | [self startCamera]; 126 | 127 | } else { 128 | NSLog(@"Setting view to overlay"); 129 | // TODO: figure out why the non-modal camera view is not working 130 | //self.view = self.overlayView; 131 | [self.camera dismissModalViewControllerAnimated:YES]; 132 | self.camera = nil; 133 | } 134 | 135 | [self.overlayView becomeFirstResponder]; 136 | } else { 137 | NSLog(@"Unable to activate camera"); 138 | } 139 | } 140 | 141 | - (void)didReceiveMemoryWarning { 142 | // Releases the view if it doesn't have a superview. 143 | [super didReceiveMemoryWarning]; 144 | 145 | // Release any cached data, images, etc that aren't in use. 146 | } 147 | 148 | - (void)viewDidUnload { 149 | // Release any retained subviews of the main view. 150 | // e.g. self.myOutlet = nil; 151 | } 152 | 153 | #pragma mark 154 | #pragma mark Touches 155 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 156 | UITouch *touch = [touches anyObject]; 157 | CGPoint point = [touch locationInView:self.view]; 158 | self.startTouchPosition = point; 159 | } 160 | 161 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 162 | UITouch *touch = [touches anyObject]; 163 | 164 | if ([touch tapCount] == 1) { 165 | [self onSingleTap:touch]; 166 | } else if ([touch tapCount] == 2) { 167 | [self onDoubleTap:touch]; 168 | } 169 | } 170 | 171 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 172 | UITouch *touch = [touches anyObject]; 173 | CGPoint currentTouchPosition = [touch locationInView:self.view]; 174 | 175 | // If the onSwipe tracks correctly. 176 | if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN && 177 | fabsf(startTouchPosition.y - currentTouchPosition.y) <= VERT_SWIPE_DRAG_MAX) 178 | { 179 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 180 | if (startTouchPosition.x < currentTouchPosition.x) { 181 | [self onSwipeRight]; 182 | } else { 183 | [self onSwipeLeft]; 184 | } 185 | self.startTouchPosition = currentTouchPosition; 186 | 187 | } else if (fabsf(startTouchPosition.y - currentTouchPosition.y) >= VERT_SWIPE_DRAG_MIN && 188 | fabsf(startTouchPosition.x - currentTouchPosition.x) <= HORIZ_SWIPE_DRAG_MAX) 189 | { 190 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 191 | if (startTouchPosition.y < currentTouchPosition.y) { 192 | [self onSwipeDown]; 193 | } else { 194 | [self onSwipeUp]; 195 | } 196 | self.startTouchPosition = currentTouchPosition; 197 | 198 | } else { 199 | // Process a non-swipe event. 200 | } 201 | } 202 | 203 | -(void)onSingleTap:(UITouch*)touch { 204 | NSLog(@"onSingleTap"); 205 | [camera takePicture]; 206 | } 207 | 208 | -(void)onDoubleTap:(UITouch*)touch { 209 | NSLog(@"onDoubleTap"); 210 | } 211 | 212 | - (void)onSwipeUp { 213 | NSLog(@"onSwipeUp"); 214 | } 215 | 216 | - (void)onSwipeDown { 217 | NSLog(@"onSwipeDown"); 218 | } 219 | 220 | - (void)onSwipeLeft { 221 | NSLog(@"onSwipeLeft"); 222 | } 223 | 224 | - (void)onSwipeRight { 225 | NSLog(@"onSwipeRight"); 226 | } 227 | 228 | - (void)buttonTapped:(id)sender { 229 | UIImageView *binocs = (UIImageView*)[self.view viewWithTag:BINOCS_TAG]; 230 | [UIView beginAnimations:nil context:nil]; 231 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 232 | [UIView setAnimationDuration:0.5f]; 233 | binocs.alpha = abs(1.0 - binocs.alpha); 234 | [UIView commitAnimations]; 235 | } 236 | 237 | - (void)thumbnailTapped:(id)sender { 238 | self.view.alpha = 1.0f; 239 | UIButton *binocsButton = (UIButton*)[self.view viewWithTag:BINOCS_BUTTON_TAG]; 240 | binocsButton.hidden = YES; 241 | } 242 | 243 | - (void)previewClosed:(id)sender { 244 | self.view.alpha = OVERLAY_ALPHA; 245 | UIButton *binocsButton = (UIButton*)[self.view viewWithTag:BINOCS_BUTTON_TAG]; 246 | binocsButton.hidden = NO; 247 | } 248 | 249 | - (void)cameraWillTakePicture:(id)sender { 250 | UIButton *binocsButton = (UIButton*)[self.view viewWithTag:BINOCS_BUTTON_TAG]; 251 | binocsButton.hidden = YES; 252 | self.overlayLabel.hidden = YES; 253 | } 254 | 255 | - (void)cameraDidTakePicture:(id)sender { 256 | UIButton *binocsButton = (UIButton*)[self.view viewWithTag:BINOCS_BUTTON_TAG]; 257 | binocsButton.hidden = NO; 258 | self.overlayLabel.hidden = NO; 259 | } 260 | 261 | - (void)dealloc { 262 | [overlayView release]; 263 | [overlayLabel release]; 264 | [camera release]; 265 | [super dealloc]; 266 | } 267 | 268 | 269 | @end 270 | -------------------------------------------------------------------------------- /HelpfulUtilities-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.yourcompany.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSMainNibFile 28 | MainWindow 29 | 30 | 31 | -------------------------------------------------------------------------------- /HelpfulUtilities.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* HelpfulUtilitiesAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* HelpfulUtilitiesAppDelegate.m */; }; 11 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 12 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 13 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 14 | 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; 15 | 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; }; 16 | 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; 17 | 28F335F11007B36200424DE2 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28F335F01007B36200424DE2 /* RootViewController.xib */; }; 18 | 4D85823F102FA63A0078CF24 /* BTLFullScreenCameraController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D85823E102FA63A0078CF24 /* BTLFullScreenCameraController.m */; }; 19 | 4D858258102FA7680078CF24 /* FullScreenCameraExampleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D858257102FA7680078CF24 /* FullScreenCameraExampleController.m */; }; 20 | 4D858435102FE20B0078CF24 /* MBProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D858434102FE20B0078CF24 /* MBProgressHUD.m */; }; 21 | 4DBBDE8E106D6D4B001D7299 /* BTLImageShareController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DBBDE8D106D6D4B001D7299 /* BTLImageShareController.m */; }; 22 | 4DBBDE9A106D6D77001D7299 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBBDE99106D6D77001D7299 /* MessageUI.framework */; }; 23 | 4DBBDEA0106D6DB8001D7299 /* overlay1.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DBBDE9F106D6DB8001D7299 /* overlay1.png */; }; 24 | 4DBBDF4A106D7940001D7299 /* binocs.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DBBDF49106D7940001D7299 /* binocs.png */; }; 25 | 4DD6280B102FA03E00B8AE1B /* Example.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DD6280A102FA03E00B8AE1B /* Example.m */; }; 26 | 4DD6538B1071D211002A2192 /* llamas.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4DD6538A1071D211002A2192 /* llamas.jpg */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 31 | 1D3623240D0F684500981E51 /* HelpfulUtilitiesAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpfulUtilitiesAppDelegate.h; sourceTree = ""; }; 32 | 1D3623250D0F684500981E51 /* HelpfulUtilitiesAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HelpfulUtilitiesAppDelegate.m; sourceTree = ""; }; 33 | 1D6058910D05DD3D006BFB54 /* HelpfulUtilities.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelpfulUtilities.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 35 | 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 36 | 28A0AAE50D9B0CCF005BE974 /* HelpfulUtilities_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelpfulUtilities_Prefix.pch; sourceTree = ""; }; 37 | 28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 38 | 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; 39 | 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; 40 | 28F335F01007B36200424DE2 /* RootViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = ""; }; 41 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | 4D85823D102FA63A0078CF24 /* BTLFullScreenCameraController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTLFullScreenCameraController.h; sourceTree = ""; }; 43 | 4D85823E102FA63A0078CF24 /* BTLFullScreenCameraController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTLFullScreenCameraController.m; sourceTree = ""; }; 44 | 4D858256102FA7680078CF24 /* FullScreenCameraExampleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FullScreenCameraExampleController.h; path = Examples/FullScreenCameraExampleController.h; sourceTree = ""; }; 45 | 4D858257102FA7680078CF24 /* FullScreenCameraExampleController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FullScreenCameraExampleController.m; path = Examples/FullScreenCameraExampleController.m; sourceTree = ""; }; 46 | 4D858433102FE20B0078CF24 /* MBProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBProgressHUD.h; sourceTree = ""; }; 47 | 4D858434102FE20B0078CF24 /* MBProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBProgressHUD.m; sourceTree = ""; }; 48 | 4DBBDE8C106D6D4B001D7299 /* BTLImageShareController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BTLImageShareController.h; sourceTree = ""; }; 49 | 4DBBDE8D106D6D4B001D7299 /* BTLImageShareController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BTLImageShareController.m; sourceTree = ""; }; 50 | 4DBBDE99106D6D77001D7299 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; 51 | 4DBBDE9F106D6DB8001D7299 /* overlay1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = overlay1.png; sourceTree = ""; }; 52 | 4DBBDF49106D7940001D7299 /* binocs.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = binocs.png; sourceTree = ""; }; 53 | 4DD62809102FA03E00B8AE1B /* Example.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Example.h; sourceTree = ""; }; 54 | 4DD6280A102FA03E00B8AE1B /* Example.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Example.m; sourceTree = ""; }; 55 | 4DD6538A1071D211002A2192 /* llamas.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = llamas.jpg; sourceTree = ""; }; 56 | 8D1107310486CEB800E47090 /* HelpfulUtilities-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "HelpfulUtilities-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 65 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 66 | 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, 67 | 4DBBDE9A106D6D77001D7299 /* MessageUI.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | 080E96DDFE201D6D7F000001 /* Classes */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 28C286DF0D94DF7D0034E888 /* RootViewController.h */, 78 | 28C286E00D94DF7D0034E888 /* RootViewController.m */, 79 | 1D3623240D0F684500981E51 /* HelpfulUtilitiesAppDelegate.h */, 80 | 1D3623250D0F684500981E51 /* HelpfulUtilitiesAppDelegate.m */, 81 | 4DD62809102FA03E00B8AE1B /* Example.h */, 82 | 4DD6280A102FA03E00B8AE1B /* Example.m */, 83 | ); 84 | path = Classes; 85 | sourceTree = ""; 86 | }; 87 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 1D6058910D05DD3D006BFB54 /* HelpfulUtilities.app */, 91 | ); 92 | name = Products; 93 | sourceTree = ""; 94 | }; 95 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 4D85823B102FA6290078CF24 /* Examples */, 99 | 4D858242102FA6F10078CF24 /* BTL Utilities */, 100 | 4D85841F102FE0E60078CF24 /* Other Utilities */, 101 | 080E96DDFE201D6D7F000001 /* Classes */, 102 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 103 | 4D8583D2102FDCF20078CF24 /* Views */, 104 | 29B97317FDCFA39411CA2CEA /* Resources */, 105 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 106 | 19C28FACFE9D520D11CA2CBB /* Products */, 107 | 4DBBDE99106D6D77001D7299 /* MessageUI.framework */, 108 | ); 109 | name = CustomTemplate; 110 | sourceTree = ""; 111 | }; 112 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 28A0AAE50D9B0CCF005BE974 /* HelpfulUtilities_Prefix.pch */, 116 | 29B97316FDCFA39411CA2CEA /* main.m */, 117 | ); 118 | name = "Other Sources"; 119 | sourceTree = ""; 120 | }; 121 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 4DD6538A1071D211002A2192 /* llamas.jpg */, 125 | 4DBBDE9F106D6DB8001D7299 /* overlay1.png */, 126 | 8D1107310486CEB800E47090 /* HelpfulUtilities-Info.plist */, 127 | 4DBBDF49106D7940001D7299 /* binocs.png */, 128 | ); 129 | name = Resources; 130 | sourceTree = ""; 131 | }; 132 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 136 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 137 | 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, 138 | ); 139 | name = Frameworks; 140 | sourceTree = ""; 141 | }; 142 | 4D85823B102FA6290078CF24 /* Examples */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 4D858256102FA7680078CF24 /* FullScreenCameraExampleController.h */, 146 | 4D858257102FA7680078CF24 /* FullScreenCameraExampleController.m */, 147 | ); 148 | name = Examples; 149 | sourceTree = ""; 150 | }; 151 | 4D858242102FA6F10078CF24 /* BTL Utilities */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 4D85823D102FA63A0078CF24 /* BTLFullScreenCameraController.h */, 155 | 4D85823E102FA63A0078CF24 /* BTLFullScreenCameraController.m */, 156 | 4DBBDE8C106D6D4B001D7299 /* BTLImageShareController.h */, 157 | 4DBBDE8D106D6D4B001D7299 /* BTLImageShareController.m */, 158 | ); 159 | path = "BTL Utilities"; 160 | sourceTree = ""; 161 | }; 162 | 4D8583D2102FDCF20078CF24 /* Views */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 28F335F01007B36200424DE2 /* RootViewController.xib */, 166 | 28AD735F0D9D9599002E5188 /* MainWindow.xib */, 167 | ); 168 | path = Views; 169 | sourceTree = ""; 170 | }; 171 | 4D85841F102FE0E60078CF24 /* Other Utilities */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 4D858433102FE20B0078CF24 /* MBProgressHUD.h */, 175 | 4D858434102FE20B0078CF24 /* MBProgressHUD.m */, 176 | ); 177 | path = "Other Utilities"; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXGroup section */ 181 | 182 | /* Begin PBXNativeTarget section */ 183 | 1D6058900D05DD3D006BFB54 /* HelpfulUtilities */ = { 184 | isa = PBXNativeTarget; 185 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelpfulUtilities" */; 186 | buildPhases = ( 187 | 1D60588D0D05DD3D006BFB54 /* Resources */, 188 | 1D60588E0D05DD3D006BFB54 /* Sources */, 189 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 190 | ); 191 | buildRules = ( 192 | ); 193 | dependencies = ( 194 | ); 195 | name = HelpfulUtilities; 196 | productName = HelpfulUtilities; 197 | productReference = 1D6058910D05DD3D006BFB54 /* HelpfulUtilities.app */; 198 | productType = "com.apple.product-type.application"; 199 | }; 200 | /* End PBXNativeTarget section */ 201 | 202 | /* Begin PBXProject section */ 203 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 204 | isa = PBXProject; 205 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelpfulUtilities" */; 206 | compatibilityVersion = "Xcode 3.1"; 207 | hasScannedForEncodings = 1; 208 | knownRegions = ( 209 | English, 210 | Japanese, 211 | French, 212 | German, 213 | en, 214 | ); 215 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 216 | projectDirPath = ""; 217 | projectRoot = ""; 218 | targets = ( 219 | 1D6058900D05DD3D006BFB54 /* HelpfulUtilities */, 220 | ); 221 | }; 222 | /* End PBXProject section */ 223 | 224 | /* Begin PBXResourcesBuildPhase section */ 225 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 226 | isa = PBXResourcesBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */, 230 | 28F335F11007B36200424DE2 /* RootViewController.xib in Resources */, 231 | 4DBBDEA0106D6DB8001D7299 /* overlay1.png in Resources */, 232 | 4DBBDF4A106D7940001D7299 /* binocs.png in Resources */, 233 | 4DD6538B1071D211002A2192 /* llamas.jpg in Resources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXResourcesBuildPhase section */ 238 | 239 | /* Begin PBXSourcesBuildPhase section */ 240 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 241 | isa = PBXSourcesBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 245 | 1D3623260D0F684500981E51 /* HelpfulUtilitiesAppDelegate.m in Sources */, 246 | 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, 247 | 4DD6280B102FA03E00B8AE1B /* Example.m in Sources */, 248 | 4D85823F102FA63A0078CF24 /* BTLFullScreenCameraController.m in Sources */, 249 | 4D858258102FA7680078CF24 /* FullScreenCameraExampleController.m in Sources */, 250 | 4D858435102FE20B0078CF24 /* MBProgressHUD.m in Sources */, 251 | 4DBBDE8E106D6D4B001D7299 /* BTLImageShareController.m in Sources */, 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | /* End PBXSourcesBuildPhase section */ 256 | 257 | /* Begin XCBuildConfiguration section */ 258 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 259 | isa = XCBuildConfiguration; 260 | buildSettings = { 261 | ALWAYS_SEARCH_USER_PATHS = NO; 262 | COPY_PHASE_STRIP = NO; 263 | GCC_DYNAMIC_NO_PIC = NO; 264 | GCC_OPTIMIZATION_LEVEL = 0; 265 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 266 | GCC_PREFIX_HEADER = HelpfulUtilities_Prefix.pch; 267 | INFOPLIST_FILE = "HelpfulUtilities-Info.plist"; 268 | PRODUCT_NAME = HelpfulUtilities; 269 | }; 270 | name = Debug; 271 | }; 272 | 1D6058950D05DD3E006BFB54 /* Release */ = { 273 | isa = XCBuildConfiguration; 274 | buildSettings = { 275 | ALWAYS_SEARCH_USER_PATHS = NO; 276 | COPY_PHASE_STRIP = YES; 277 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 278 | GCC_PREFIX_HEADER = HelpfulUtilities_Prefix.pch; 279 | INFOPLIST_FILE = "HelpfulUtilities-Info.plist"; 280 | PRODUCT_NAME = HelpfulUtilities; 281 | }; 282 | name = Release; 283 | }; 284 | C01FCF4F08A954540054247B /* Debug */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 289 | GCC_C_LANGUAGE_STANDARD = c99; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 291 | GCC_WARN_UNUSED_VARIABLE = YES; 292 | PREBINDING = NO; 293 | SDKROOT = iphoneos3.1; 294 | }; 295 | name = Debug; 296 | }; 297 | C01FCF5008A954540054247B /* Release */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 301 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 302 | GCC_C_LANGUAGE_STANDARD = c99; 303 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 304 | GCC_WARN_UNUSED_VARIABLE = YES; 305 | PREBINDING = NO; 306 | SDKROOT = iphoneos3.1; 307 | }; 308 | name = Release; 309 | }; 310 | /* End XCBuildConfiguration section */ 311 | 312 | /* Begin XCConfigurationList section */ 313 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelpfulUtilities" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | 1D6058940D05DD3E006BFB54 /* Debug */, 317 | 1D6058950D05DD3E006BFB54 /* Release */, 318 | ); 319 | defaultConfigurationIsVisible = 0; 320 | defaultConfigurationName = Release; 321 | }; 322 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelpfulUtilities" */ = { 323 | isa = XCConfigurationList; 324 | buildConfigurations = ( 325 | C01FCF4F08A954540054247B /* Debug */, 326 | C01FCF5008A954540054247B /* Release */, 327 | ); 328 | defaultConfigurationIsVisible = 0; 329 | defaultConfigurationName = Release; 330 | }; 331 | /* End XCConfigurationList section */ 332 | }; 333 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 334 | } 335 | -------------------------------------------------------------------------------- /HelpfulUtilities_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'HelpfulUtilities' target in the 'HelpfulUtilities' project 3 | // 4 | #import 5 | 6 | #ifndef __IPHONE_3_0 7 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 8 | #endif 9 | 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | 16 | // Comment out this line to exclude thumbnail previews and picture sharing. 17 | // Sharing requires MessageUI framework to send pictures as email attachments. 18 | #define BTL_INCLUDE_IMAGE_SHARING 1 19 | 20 | -------------------------------------------------------------------------------- /Other Utilities/MBProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // MBProgressHUD.h 3 | // Version 0.2 4 | // Created by Matej Bukovinski on 21.7.09. 5 | // 6 | 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | 9 | // Copyright (c) 2009 Matej Bukovinski 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | 31 | /** 32 | * MBProgressHUD operation modes. 33 | */ 34 | typedef enum { 35 | /** Progress is shown using an UIActivityIndicatorView. This is the default. */ 36 | MBProgressHUDModeIndeterminate, 37 | /** Progress is shown using a MBRoundProgressView. */ 38 | MBProgressHUDModeDeterminate, 39 | } MBProgressHUDMode; 40 | 41 | /** 42 | * Displays a simple HUD window containing a UIActivityIndicatorView and two optional labels for short messages. 43 | * 44 | * This is a simple drop-in class for displaying a progress HUD view similar to Apples private UIProgressHUD class. 45 | * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all user 46 | * input on this region, thereby preventing the user operations on components below the view. 47 | * The HUD itself is drawn centered as a rounded semi-transparent view witch resizes depending on the user specified content. 48 | * This view supports three modes of operation: 49 | * - The default mode displays just a UIActivityIndicatorView. 50 | * - If the labelText property is set and non-empty then a label containing the provided content is placed below the UIActivityIndicatorView. 51 | * - If also the detailsLabelText property is set then another label is placed below the firs label. 52 | */ 53 | @interface MBProgressHUD : UIView { 54 | 55 | MBProgressHUDMode mode; 56 | 57 | SEL methodForExecution; 58 | id targetForExecution; 59 | id objectForExecution; 60 | bool useAnimation; 61 | 62 | float width; 63 | float height; 64 | 65 | UIView *indicator; 66 | UILabel *label; 67 | UILabel *detailsLabel; 68 | 69 | float progress; 70 | 71 | id delegate; 72 | NSString *labelText; 73 | NSString *detailsLabelText; 74 | float opacity; 75 | UIFont *labelFont; 76 | UIFont *detailsLabelFont; 77 | } 78 | 79 | /** 80 | * A convenience constructor tat initializes the HUD with the window's bounds. 81 | * Calls the designated constructor with window.bounds as the parameter. 82 | */ 83 | - (id)initWithWindow:(UIWindow *)window; 84 | 85 | /** 86 | * MBProgressHUD operation mode. Switches between indeterminate (MBProgressHUDModeIndeterminate) 87 | * and determinate progress (MBProgressHUDModeDeterminate). The default is MBProgressHUDModeIndeterminate. 88 | */ 89 | @property (assign) MBProgressHUDMode mode; 90 | 91 | /** 92 | * The HUD delegate object. If set the delegate will receive hudWasHidden callbacks when the hud was hidden. 93 | * The delegate should conform to the MBProgressHUDDelegate protocol and implement the hudWasHidden method. 94 | * The delegate object will not be retained. 95 | */ 96 | @property (assign) id delegate; 97 | 98 | /** 99 | * An optional short message to be displayed below the activity indicator. 100 | * The HUD is automatically resized to fit the entire text. If the text is too long it will get clipped by displaying "..." at the end. 101 | * If left unchanged or set to @"", then no message is displayed. 102 | */ 103 | @property (copy) NSString *labelText; 104 | 105 | /** 106 | * An optional details message displayed below the labelText message. 107 | * This message is displayed only if the labelText property is also set and is different from an empty string (@""). 108 | */ 109 | @property (copy) NSString *detailsLabelText; 110 | 111 | /** 112 | * The opacity of the hud window. 113 | * Defaults to 0.9 (90% opacity). 114 | */ 115 | @property (assign) float opacity; 116 | 117 | /** 118 | * Font to be used for the main label. 119 | * Set this property if the default is not adequate. 120 | */ 121 | @property (retain) UIFont *labelFont; 122 | 123 | /** 124 | * Font to be used for the details label. 125 | * Set this property if the default is not adequate. 126 | */ 127 | @property (retain) UIFont *detailsLabelFont; 128 | 129 | /** 130 | * The progress of the progress indicator, from 0.0 to 1.0. 131 | * Defaults to 0.0. 132 | */ 133 | @property (assign) float progress; 134 | 135 | /** 136 | * Shows the HUD while a background task is executing in a new thread, then hides the HUD. 137 | * 138 | * This method also takes care of NSAutoreleasePools so your method does not have to be concerned with setting up a pool. 139 | * 140 | * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread. 141 | * @param target The object that the target method belongs to. 142 | * @param object An optional object to be passed to the method. 143 | * @param animated If set to YES the HUD will appear and disappear using a fade animation. 144 | * If set to NO the HUD will not use animations while appearing and disappearing. 145 | */ 146 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(bool)animated; 147 | 148 | @end 149 | 150 | 151 | /** 152 | * Defines callback methods for MBProgressHUD delegates. 153 | */ 154 | @protocol MBProgressHUDDelegate 155 | 156 | /** 157 | * A callback function that is called after the hud was fully hidden from the screen. 158 | */ 159 | - (void)hudWasHidden; 160 | 161 | @end 162 | 163 | /** 164 | * A progress view for showing definite progress by filling up a circle (similar to the indicator for building in xcode). 165 | */ 166 | @interface MBRoundProgressView : UIProgressView { 167 | 168 | } 169 | 170 | /** 171 | * Create a 37 by 37 pixel indicator. 172 | * This is the same size as used by the larger UIActivityIndicatorView. 173 | */ 174 | - (id)initWithDefaultSize; 175 | 176 | @end -------------------------------------------------------------------------------- /Other Utilities/MBProgressHUD.m: -------------------------------------------------------------------------------- 1 | // 2 | // MBProgressHUD.m 3 | // Version 0.2 4 | // Created by Matej Bukovinski on 21.7.09. 5 | // 6 | 7 | #import "MBProgressHUD.h" 8 | 9 | @interface MBProgressHUD () 10 | 11 | - (void)hideUsingAnimation:(BOOL)animated; 12 | - (void)showUsingAnimation:(BOOL)animated; 13 | 14 | - (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context; 15 | 16 | - (void)done; 17 | 18 | - (void)updateLabelText:(NSString *)newText; 19 | - (void)updateDetailsLabelText:(NSString *)newText; 20 | - (void)updateProgress; 21 | - (void)updateIndicators; 22 | 23 | @property (retain) UIView *indicator; 24 | 25 | @property (assign) float width; 26 | @property (assign) float height; 27 | 28 | @end 29 | 30 | 31 | 32 | @implementation MBProgressHUD 33 | 34 | #pragma mark Accessors 35 | 36 | @synthesize mode; 37 | 38 | @synthesize delegate; 39 | @synthesize labelText; 40 | @synthesize detailsLabelText; 41 | @synthesize opacity; 42 | @synthesize labelFont; 43 | @synthesize detailsLabelFont; 44 | @synthesize progress; 45 | 46 | @synthesize indicator; 47 | 48 | @synthesize width; 49 | @synthesize height; 50 | 51 | - (void)setMode:(MBProgressHUDMode)newMode { 52 | mode = newMode; 53 | [self performSelectorOnMainThread:@selector(updateIndicators) withObject:nil waitUntilDone:NO]; 54 | [self performSelectorOnMainThread:@selector(layoutAndStyle) withObject:nil waitUntilDone:NO]; 55 | [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 56 | } 57 | 58 | - (void)setLabelText:(NSString *)newText { 59 | [self performSelectorOnMainThread:@selector(updateLabelText:) withObject:newText waitUntilDone:NO]; 60 | [self performSelectorOnMainThread:@selector(layoutAndStyle) withObject:nil waitUntilDone:NO]; 61 | [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 62 | } 63 | 64 | - (void)setDetailsLabelText:(NSString *)newText { 65 | [self performSelectorOnMainThread:@selector(updateDetailsLabelText:) withObject:newText waitUntilDone:NO]; 66 | [self performSelectorOnMainThread:@selector(layoutAndStyle) withObject:nil waitUntilDone:NO]; 67 | [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 68 | } 69 | 70 | - (void)setProgress:(float)newProgress { 71 | progress = newProgress; 72 | // Update display ony if showind the determinate progress view 73 | if (mode == MBProgressHUDModeDeterminate) { 74 | [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO]; 75 | [self performSelectorOnMainThread:@selector(layoutAndStyle) withObject:nil waitUntilDone:NO]; 76 | [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; 77 | } 78 | } 79 | 80 | #pragma mark Acessor heplers 81 | 82 | - (void)updateLabelText:(NSString *)newText { 83 | if (labelText != newText) { 84 | [labelText release]; 85 | labelText = [newText copy]; 86 | } 87 | } 88 | 89 | - (void)updateDetailsLabelText:(NSString *)newText { 90 | if (detailsLabelText != newText) { 91 | [detailsLabelText release]; 92 | detailsLabelText = [newText copy]; 93 | } 94 | } 95 | 96 | - (void)updateProgress { 97 | [(MBRoundProgressView *)indicator setProgress:progress]; 98 | } 99 | 100 | - (void)updateIndicators { 101 | if (indicator) [indicator removeFromSuperview]; 102 | if (mode == MBProgressHUDModeDeterminate) 103 | self.indicator = [[MBRoundProgressView alloc] initWithDefaultSize]; 104 | else { 105 | self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 106 | [(UIActivityIndicatorView *)indicator startAnimating]; 107 | } 108 | [self addSubview:indicator]; 109 | } 110 | 111 | 112 | #pragma mark Build up 113 | 114 | #define MARGIN 20.0 115 | #define PADDING 4.0 116 | 117 | #define LABELFONTSIZE 22.0 118 | #define LABELDETAILSFONTSIZE 16.0 119 | 120 | - (id)initWithWindow:(UIWindow* )window { 121 | return [self initWithFrame:window.bounds]; 122 | } 123 | 124 | - (id)initWithFrame:(CGRect)frame { 125 | if (self = [super initWithFrame:frame]) { 126 | // Set default values for properties 127 | self.mode = MBProgressHUDModeIndeterminate; 128 | self.labelText = @""; 129 | self.detailsLabelText = @""; 130 | self.opacity = 0.9; 131 | self.labelFont = [UIFont boldSystemFontOfSize:LABELFONTSIZE]; 132 | self.detailsLabelFont = [UIFont boldSystemFontOfSize:LABELDETAILSFONTSIZE]; 133 | 134 | // Transparent background 135 | self.opaque = NO; 136 | self.backgroundColor = [UIColor clearColor]; 137 | 138 | // Make invisible for now 139 | self.alpha = 0.0; 140 | 141 | // Add label 142 | label = [[UILabel alloc] initWithFrame:self.bounds]; 143 | 144 | // Add details label 145 | detailsLabel = [[UILabel alloc] initWithFrame:self.bounds]; 146 | } 147 | return self; 148 | } 149 | 150 | - (void)layoutAndStyle { 151 | 152 | CGRect frame = self.bounds; 153 | 154 | // Compute HUD dimensions based on indicator size (add margin to HUD border) 155 | CGRect indFrame = indicator.bounds; 156 | self.width = indFrame.size.width + 2*MARGIN; 157 | self.height = indFrame.size.height + 2*MARGIN; 158 | 159 | // Center the indicator 160 | indFrame.origin.x = (frame.size.width-indFrame.size.width)/2; 161 | indFrame.origin.y = (frame.size.height-indFrame.size.height)/2; 162 | indicator.frame = indFrame; 163 | 164 | // Add label if label text was set 165 | if (self.labelText != @"") { 166 | 167 | // Get size of label text 168 | CGSize dims = [self.labelText sizeWithFont:self.labelFont]; 169 | 170 | // Compute label dimensions based on font metrics 171 | // if size is larger than max then clip the label width 172 | float lHeight = dims.height; 173 | float lWidth; 174 | if (dims.width <= (frame.size.width - 2*MARGIN)) 175 | lWidth = dims.width; 176 | else 177 | lWidth = frame.size.width - 4*MARGIN; 178 | 179 | // Set label porperties 180 | label.font = self.labelFont; 181 | label.adjustsFontSizeToFitWidth = NO; 182 | label.textAlignment = UITextAlignmentCenter; 183 | label.opaque = NO; 184 | label.backgroundColor = [UIColor clearColor]; 185 | label.textColor = [UIColor whiteColor]; 186 | label.text = self.labelText; 187 | 188 | // Update HUD size 189 | if (self.width < (lWidth + 2*MARGIN)) 190 | self.width = lWidth + 2*MARGIN; 191 | self.height = self.height + lHeight + PADDING; 192 | 193 | // Move indicator to make room for the label 194 | indFrame.origin.y -= (lHeight/2 + PADDING/2); 195 | indicator.frame = indFrame; 196 | 197 | // Set the label position and dimensions 198 | CGRect lFrame = CGRectMake((frame.size.width-lWidth)/2, indFrame.origin.y + indFrame.size.height + PADDING, lWidth, lHeight); 199 | label.frame = lFrame; 200 | 201 | [self addSubview:label]; 202 | 203 | // Add details label delatils text was set 204 | if (self.detailsLabelText != @"") { 205 | 206 | // Get size of label text 207 | dims = [self.detailsLabelText sizeWithFont:self.detailsLabelFont]; 208 | 209 | // Compute label dimensions based on font metrics 210 | // if size is larger than max then clip the label width 211 | lHeight = dims.height; 212 | if (dims.width <= (frame.size.width - 2*MARGIN)) 213 | lWidth = dims.width; 214 | else 215 | lWidth = frame.size.width - 4*MARGIN; 216 | 217 | // Set label properties 218 | detailsLabel.font = self.detailsLabelFont; 219 | detailsLabel.adjustsFontSizeToFitWidth = NO; 220 | detailsLabel.textAlignment = UITextAlignmentCenter; 221 | detailsLabel.opaque = NO; 222 | detailsLabel.backgroundColor = [UIColor clearColor]; 223 | detailsLabel.textColor = [UIColor whiteColor]; 224 | detailsLabel.text = self.detailsLabelText; 225 | 226 | // Update HUD size 227 | if (self.width < lWidth) 228 | self.width = lWidth + 2*MARGIN; 229 | self.height = self.height + lHeight + PADDING; 230 | 231 | // Move indicator to make room for the new label 232 | indFrame.origin.y -= (lHeight/2 + PADDING/2); 233 | indicator.frame = indFrame; 234 | 235 | // Move first label to make room for the new label 236 | lFrame.origin.y -= (lHeight/2 + PADDING/2); 237 | label.frame = lFrame; 238 | 239 | // Set label position and dimensions 240 | CGRect lFrameD = CGRectMake((frame.size.width-lWidth)/2, lFrame.origin.y + lFrame.size.height + PADDING, lWidth, lHeight); 241 | detailsLabel.frame = lFrameD; 242 | 243 | [self addSubview:detailsLabel]; 244 | 245 | } 246 | } 247 | } 248 | 249 | #pragma mark Showing and execution 250 | 251 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(bool)animated { 252 | 253 | [self layoutAndStyle]; 254 | [self setNeedsDisplay]; 255 | 256 | methodForExecution = method; 257 | targetForExecution = [target retain]; 258 | objectForExecution = [object retain]; 259 | useAnimation = animated; 260 | 261 | // Show HUD view 262 | [self showUsingAnimation:useAnimation]; 263 | 264 | // Launch execution in new thread 265 | [NSThread detachNewThreadSelector:@selector(launchExecution) toTarget:self withObject:nil]; 266 | } 267 | 268 | - (void)launchExecution { 269 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 270 | 271 | // Start executing the requested task 272 | [targetForExecution performSelector:methodForExecution withObject:objectForExecution]; 273 | 274 | // Task completed, update view in main thread (note: view operations should be done only in the main thread) 275 | [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO]; 276 | 277 | [pool release]; 278 | } 279 | 280 | - (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context { 281 | [self done]; 282 | } 283 | 284 | - (void)done { 285 | // If delegate was set make the callback 286 | if (delegate != nil && [delegate respondsToSelector:@selector(hudWasHidden)]) { 287 | [delegate hudWasHidden]; 288 | } else { 289 | [NSException raise:NSInternalInconsistencyException format:@"Delegate doesn't respond to hudWasHidden"]; 290 | } 291 | } 292 | 293 | - (void)cleanUp { 294 | [targetForExecution release]; 295 | [objectForExecution release]; 296 | 297 | [self hideUsingAnimation:useAnimation]; 298 | } 299 | 300 | #pragma mark Fade in and Fade out 301 | 302 | - (void)showUsingAnimation:(BOOL)animated { 303 | // Fade in 304 | if (animated) { 305 | [UIView beginAnimations:nil context:NULL]; 306 | [UIView setAnimationDuration:0.40]; 307 | self.alpha = 1.0; 308 | [UIView commitAnimations]; 309 | } else { 310 | self.alpha = 1.0; 311 | } 312 | } 313 | 314 | - (void)hideUsingAnimation:(BOOL)animated { 315 | // Fade in 316 | if (animated) { 317 | [UIView beginAnimations:nil context:NULL]; 318 | [UIView setAnimationDuration:0.40]; 319 | [UIView setAnimationDelegate:self]; 320 | [UIView setAnimationDidStopSelector:@selector(animationFinished: finished: context:)]; 321 | self.alpha = 0.0; 322 | [UIView commitAnimations]; 323 | } else { 324 | self.alpha = 0.0; 325 | [self done]; 326 | } 327 | } 328 | 329 | #pragma mark BG Drawing 330 | 331 | - (void)drawRect:(CGRect)rect { 332 | // Center HUD 333 | CGRect allRect = self.bounds; 334 | // Draw rounded HUD bacgroud rect 335 | CGRect boxRect = CGRectMake((allRect.size.width-self.width)/2 , (allRect.size.height-self.height)/2, self.width, self.height); 336 | CGContextRef ctxt = UIGraphicsGetCurrentContext(); 337 | [self fillRoundedRect:boxRect inContext:ctxt]; 338 | } 339 | 340 | - (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context { 341 | 342 | float radius = 10.0f; 343 | 344 | CGContextBeginPath(context); 345 | CGContextSetGrayFillColor(context, 0.0, self.opacity); 346 | CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect)); 347 | CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect) + radius, radius, 3 * M_PI / 2, 0, 0); 348 | CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect) - radius, radius, 0, M_PI / 2, 0); 349 | CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius, radius, M_PI / 2, M_PI, 0); 350 | CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) + radius, radius, M_PI, 3 * M_PI / 2, 0); 351 | 352 | CGContextClosePath(context); 353 | CGContextFillPath(context); 354 | } 355 | 356 | #pragma mark Tear down 357 | 358 | - (void)dealloc { 359 | [indicator release]; 360 | [label release]; 361 | [detailsLabel release]; 362 | [labelText release]; 363 | [detailsLabelText release]; 364 | [super dealloc]; 365 | } 366 | 367 | 368 | @end 369 | 370 | #define PI 3.14159265358979323846 371 | 372 | @implementation MBRoundProgressView 373 | 374 | - (id)initWithDefaultSize { 375 | return [super initWithFrame:CGRectMake(0.0f, 0.0f, 37.0f, 37.0f)]; 376 | } 377 | 378 | - (void)drawRect:(CGRect)rect { 379 | CGRect allRect = self.bounds; 380 | CGRect circleRect = CGRectMake(allRect.origin.x + 2, allRect.origin.y + 2, 381 | allRect.size.width - 4, allRect.size.height - 4); 382 | 383 | CGContextRef context = UIGraphicsGetCurrentContext(); 384 | 385 | // Draw background 386 | CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); // white 387 | CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.1); // translucent white 388 | CGContextSetLineWidth(context, 2.0); 389 | CGContextFillEllipseInRect(context, circleRect); 390 | CGContextStrokeEllipseInRect(context, circleRect); 391 | 392 | // Draw progress 393 | float x = allRect.size.width / 2; 394 | float y = allRect.size.height / 2; 395 | CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); // white 396 | CGContextMoveToPoint(context, x, y); 397 | CGContextAddArc(context, x, y, (allRect.size.width-4)/2, -PI/2, (self.progress*2*PI)-PI/2, 0); 398 | CGContextClosePath(context); 399 | CGContextFillPath(context); 400 | } 401 | 402 | @end 403 | -------------------------------------------------------------------------------- /Views/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 784 5 | 9J61 6 | 680 7 | 949.46 8 | 353.00 9 | 10 | YES 11 | 12 | 13 | 14 | YES 15 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 16 | 17 | 18 | YES 19 | 20 | YES 21 | 22 | 23 | YES 24 | 25 | 26 | 27 | YES 28 | 29 | IBFilesOwner 30 | 31 | 32 | IBFirstResponder 33 | 34 | 35 | 36 | 37 | 1316 38 | 39 | {320, 480} 40 | 41 | 1 42 | MSAxIDEAA 43 | 44 | NO 45 | NO 46 | 47 | 48 | 49 | 50 | 51 | 52 | 256 53 | {0, 0} 54 | NO 55 | YES 56 | YES 57 | 58 | 59 | YES 60 | 61 | 62 | 63 | Helpful Utilities 64 | Bordertown Labs gives you 65 | 66 | Back 67 | 1 68 | 69 | 70 | 71 | RootViewController 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | YES 80 | 81 | 82 | delegate 83 | 84 | 85 | 86 | 4 87 | 88 | 89 | 90 | window 91 | 92 | 93 | 94 | 5 95 | 96 | 97 | 98 | navigationController 99 | 100 | 101 | 102 | 15 103 | 104 | 105 | 106 | 107 | YES 108 | 109 | 0 110 | 111 | YES 112 | 113 | 114 | 115 | 116 | 117 | 2 118 | 119 | 120 | YES 121 | 122 | 123 | 124 | 125 | -1 126 | 127 | 128 | RmlsZSdzIE93bmVyA 129 | 130 | 131 | 3 132 | 133 | 134 | 135 | 136 | -2 137 | 138 | 139 | 140 | 141 | 9 142 | 143 | 144 | YES 145 | 146 | 147 | 148 | 149 | 150 | 151 | 11 152 | 153 | 154 | 155 | 156 | 13 157 | 158 | 159 | YES 160 | 161 | 162 | 163 | 164 | 165 | 14 166 | 167 | 168 | YES 169 | 170 | 171 | 172 | 173 | 174 | 16 175 | 176 | 177 | 178 | 179 | 180 | 181 | YES 182 | 183 | YES 184 | -1.CustomClassName 185 | -2.CustomClassName 186 | 11.IBPluginDependency 187 | 13.CustomClassName 188 | 13.IBPluginDependency 189 | 2.IBAttributePlaceholdersKey 190 | 2.IBEditorWindowLastContentRect 191 | 2.IBPluginDependency 192 | 3.CustomClassName 193 | 3.IBPluginDependency 194 | 9.IBEditorWindowLastContentRect 195 | 9.IBPluginDependency 196 | 197 | 198 | YES 199 | UIApplication 200 | UIResponder 201 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 202 | RootViewController 203 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 204 | 205 | YES 206 | 207 | YES 208 | 209 | 210 | YES 211 | 212 | 213 | {{673, 376}, {320, 480}} 214 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 215 | HelpfulUtilitiesAppDelegate 216 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 217 | {{343, 29}, {320, 480}} 218 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 219 | 220 | 221 | 222 | YES 223 | 224 | YES 225 | 226 | 227 | YES 228 | 229 | 230 | 231 | 232 | YES 233 | 234 | YES 235 | 236 | 237 | YES 238 | 239 | 240 | 241 | 16 242 | 243 | 244 | 245 | YES 246 | 247 | HelpfulUtilitiesAppDelegate 248 | NSObject 249 | 250 | YES 251 | 252 | YES 253 | navigationController 254 | window 255 | 256 | 257 | YES 258 | UINavigationController 259 | UIWindow 260 | 261 | 262 | 263 | IBProjectSource 264 | Classes/HelpfulUtilitiesAppDelegate.h 265 | 266 | 267 | 268 | RootViewController 269 | UITableViewController 270 | 271 | IBProjectSource 272 | Classes/RootViewController.h 273 | 274 | 275 | 276 | 277 | 0 278 | HelpfulUtilities.xcodeproj 279 | 3 280 | 3.1 281 | 282 | 283 | -------------------------------------------------------------------------------- /Views/RootViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 784 5 | 10A405 6 | 732 7 | 1031 8 | 432.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 62 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | 35 | 36 | IBFirstResponder 37 | 38 | 39 | 40 | 274 41 | {320, 247} 42 | 43 | 44 | 3 45 | MQA 46 | 47 | NO 48 | YES 49 | NO 50 | NO 51 | 1 52 | 0 53 | YES 54 | 44 55 | 22 56 | 22 57 | 58 | 59 | 60 | 61 | YES 62 | 63 | 64 | view 65 | 66 | 67 | 68 | 3 69 | 70 | 71 | 72 | dataSource 73 | 74 | 75 | 76 | 4 77 | 78 | 79 | 80 | delegate 81 | 82 | 83 | 84 | 5 85 | 86 | 87 | 88 | 89 | YES 90 | 91 | 0 92 | 93 | 94 | 95 | 96 | 97 | -1 98 | 99 | 100 | File's Owner 101 | 102 | 103 | -2 104 | 105 | 106 | 107 | 108 | 2 109 | 110 | 111 | 112 | 113 | 114 | 115 | YES 116 | 117 | YES 118 | -1.CustomClassName 119 | -2.CustomClassName 120 | 2.IBEditorWindowLastContentRect 121 | 2.IBPluginDependency 122 | 123 | 124 | YES 125 | RootViewController 126 | UIResponder 127 | {{0, 598}, {320, 247}} 128 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 129 | 130 | 131 | 132 | YES 133 | 134 | 135 | YES 136 | 137 | 138 | 139 | 140 | YES 141 | 142 | 143 | YES 144 | 145 | 146 | 147 | 5 148 | 149 | 150 | 151 | YES 152 | 153 | RootViewController 154 | UITableViewController 155 | 156 | IBProjectSource 157 | Classes/RootViewController.h 158 | 159 | 160 | 161 | 162 | YES 163 | 164 | NSObject 165 | 166 | IBFrameworkSource 167 | Foundation.framework/Headers/NSError.h 168 | 169 | 170 | 171 | NSObject 172 | 173 | IBFrameworkSource 174 | Foundation.framework/Headers/NSFileManager.h 175 | 176 | 177 | 178 | NSObject 179 | 180 | IBFrameworkSource 181 | Foundation.framework/Headers/NSKeyValueCoding.h 182 | 183 | 184 | 185 | NSObject 186 | 187 | IBFrameworkSource 188 | Foundation.framework/Headers/NSKeyValueObserving.h 189 | 190 | 191 | 192 | NSObject 193 | 194 | IBFrameworkSource 195 | Foundation.framework/Headers/NSKeyedArchiver.h 196 | 197 | 198 | 199 | NSObject 200 | 201 | IBFrameworkSource 202 | Foundation.framework/Headers/NSNetServices.h 203 | 204 | 205 | 206 | NSObject 207 | 208 | IBFrameworkSource 209 | Foundation.framework/Headers/NSObject.h 210 | 211 | 212 | 213 | NSObject 214 | 215 | IBFrameworkSource 216 | Foundation.framework/Headers/NSPort.h 217 | 218 | 219 | 220 | NSObject 221 | 222 | IBFrameworkSource 223 | Foundation.framework/Headers/NSRunLoop.h 224 | 225 | 226 | 227 | NSObject 228 | 229 | IBFrameworkSource 230 | Foundation.framework/Headers/NSStream.h 231 | 232 | 233 | 234 | NSObject 235 | 236 | IBFrameworkSource 237 | Foundation.framework/Headers/NSThread.h 238 | 239 | 240 | 241 | NSObject 242 | 243 | IBFrameworkSource 244 | Foundation.framework/Headers/NSURL.h 245 | 246 | 247 | 248 | NSObject 249 | 250 | IBFrameworkSource 251 | Foundation.framework/Headers/NSURLConnection.h 252 | 253 | 254 | 255 | NSObject 256 | 257 | IBFrameworkSource 258 | Foundation.framework/Headers/NSXMLParser.h 259 | 260 | 261 | 262 | NSObject 263 | 264 | IBFrameworkSource 265 | UIKit.framework/Headers/UIAccessibility.h 266 | 267 | 268 | 269 | NSObject 270 | 271 | IBFrameworkSource 272 | UIKit.framework/Headers/UINibLoading.h 273 | 274 | 275 | 276 | NSObject 277 | 278 | IBFrameworkSource 279 | UIKit.framework/Headers/UIResponder.h 280 | 281 | 282 | 283 | UIResponder 284 | NSObject 285 | 286 | 287 | 288 | UIScrollView 289 | UIView 290 | 291 | IBFrameworkSource 292 | UIKit.framework/Headers/UIScrollView.h 293 | 294 | 295 | 296 | UISearchBar 297 | UIView 298 | 299 | IBFrameworkSource 300 | UIKit.framework/Headers/UISearchBar.h 301 | 302 | 303 | 304 | UISearchDisplayController 305 | NSObject 306 | 307 | IBFrameworkSource 308 | UIKit.framework/Headers/UISearchDisplayController.h 309 | 310 | 311 | 312 | UITableView 313 | UIScrollView 314 | 315 | IBFrameworkSource 316 | UIKit.framework/Headers/UITableView.h 317 | 318 | 319 | 320 | UITableViewController 321 | UIViewController 322 | 323 | IBFrameworkSource 324 | UIKit.framework/Headers/UITableViewController.h 325 | 326 | 327 | 328 | UIView 329 | 330 | IBFrameworkSource 331 | UIKit.framework/Headers/UITextField.h 332 | 333 | 334 | 335 | UIView 336 | UIResponder 337 | 338 | IBFrameworkSource 339 | UIKit.framework/Headers/UIView.h 340 | 341 | 342 | 343 | UIViewController 344 | 345 | IBFrameworkSource 346 | UIKit.framework/Headers/UINavigationController.h 347 | 348 | 349 | 350 | UIViewController 351 | 352 | IBFrameworkSource 353 | UIKit.framework/Headers/UITabBarController.h 354 | 355 | 356 | 357 | UIViewController 358 | UIResponder 359 | 360 | IBFrameworkSource 361 | UIKit.framework/Headers/UIViewController.h 362 | 363 | 364 | 365 | 366 | 0 367 | 368 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 369 | 370 | 371 | 372 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 373 | 374 | 375 | YES 376 | HelpfulUtilities.xcodeproj 377 | 3 378 | 3.1 379 | 380 | 381 | -------------------------------------------------------------------------------- /binocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmark/Helpful-iPhone-Utilities/53c04534b138af20c1fd5e07188dbdf64b4a69f1/binocs.png -------------------------------------------------------------------------------- /llamas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmark/Helpful-iPhone-Utilities/53c04534b138af20c1fd5e07188dbdf64b4a69f1/llamas.jpg -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HelpfulUtilities 4 | // 5 | // Created by P. Mark Anderson on 8/9/09. 6 | // Copyright 2009 Bordertown Labs, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /overlay1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pmark/Helpful-iPhone-Utilities/53c04534b138af20c1fd5e07188dbdf64b4a69f1/overlay1.png --------------------------------------------------------------------------------