Overlay controller used to provide custom Overlay on your screen when you want to provide custom options in Camera Interface.
#import "OverlayViewController.h"
enum
{
kOneShot, // user wants to take a delayed single shot
kRepeatingShot // user wants to take repeating shots
};
@implementation OverlayViewController
@synthesize delegate, takePictureButton, startStopButton,
cancelButton, timedButton,
tickTimer, cameraTimer,
imagePickerController;
#pragma mark -
#pragma mark OverlayViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:
[[NSBundle mainBundle] pathForResource:@"tick"
ofType:@"aiff"]],
&tickSound);
self.imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
self.imagePickerController.delegate = self;
}
return self;
}
- (void)viewDidUnload
{
self.takePictureButton = nil;
self.startStopButton = nil;
self.timedButton = nil;
self.cancelButton = nil;
self.cameraTimer = nil;
[super viewDidUnload];
}
- (void)dealloc
{
[takePictureButton release];
[startStopButton release];
[cancelButton release];
[timedButton release];
[imagePickerController release];
AudioServicesDisposeSystemSoundID(tickSound);
[cameraTimer release];
[tickTimer release];
[super dealloc];
}
- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType
{
self.imagePickerController.sourceType = sourceType;
if (sourceType == UIImagePickerControllerSourceTypeCamera)
{
// user wants to use the camera interface
//
self.imagePickerController.showsCameraControls = NO;
if ([[self.imagePickerController.cameraOverlayView subviews] count] == 0)
{
// setup our custom overlay view for the camera
//
// ensure that our custom view's frame fits within the parent frame
CGRect overlayViewFrame = self.imagePickerController.cameraOverlayView.frame;
CGRect newFrame = CGRectMake(0.0,
CGRectGetHeight(overlayViewFrame) -
self.view.frame.size.height - 10.0,
CGRectGetWidth(overlayViewFrame),
self.view.frame.size.height + 10.0);
self.view.frame = newFrame;
[self.imagePickerController.cameraOverlayView addSubview:self.view];
}
}
}
// called when the parent application receives a memory warning
- (void)didReceiveMemoryWarning
{
// we have been warned that memory is getting low, stop all timers
//
[super didReceiveMemoryWarning];
// stop all timers
[self.cameraTimer invalidate];
cameraTimer = nil;
[self.tickTimer invalidate];
tickTimer = nil;
}
// update the UI after an image has been chosen or picture taken
//
- (void)finishAndUpdate
{
[self.delegate didFinishWithCamera]; // tell our delegate we are done with the camera
// restore the state of our overlay toolbar buttons
self.cancelButton.enabled = YES;
self.takePictureButton.enabled = YES;
self.timedButton.enabled = YES;
self.startStopButton.enabled = YES;
self.startStopButton.title = @"Start";
}
#pragma mark -
#pragma mark Camera Actions
- (IBAction)done:(id)sender
{
// dismiss the camera
//
// but not if it's still taking timed pictures
if (![self.cameraTimer isValid])
[self finishAndUpdate];
}
// this will take a timed photo, to be taken 5 seconds from now
//
- (IBAction)timedTakePhoto:(id)sender
{
// these controls can't be used until the photo has been taken
self.cancelButton.enabled = NO;
self.takePictureButton.enabled = NO;
self.timedButton.enabled = NO;
self.startStopButton.enabled = NO;
if (cameraTimer != nil)
[cameraTimer invalidate];
cameraTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(timedPhotoFire:)
userInfo:[NSNumber numberWithInt:kOneShot]
repeats:YES];
// start the timer to sound off a tick every 1 second (sound effect before a timed picture is taken)
if (tickTimer != nil)
[tickTimer invalidate];
tickTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(tickFire:)
userInfo:nil
repeats:YES];
}
- (IBAction)takePhoto:(id)sender
{
[self.imagePickerController takePicture];
}
- (IBAction)startStop:(id)sender
{
if ([self.cameraTimer isValid])
{
// stop and reset the timer
[self.cameraTimer invalidate];
cameraTimer = nil;
[self finishAndUpdate];
}
else
{
// start the timer to take a photo every 1.5 seconds
//
// CAUTION: for the purpose of this sample, we will continue to take pictures indefinitely.
// Be aware we will run out of memory quickly. You must decide the proper threshold
// number of photos allowed to take from the camera.
//
// One solution to avoid memory constraints is to save each taken photo to disk rather
// than keeping all of them in memory.
//
// In low memory situations sometimes our "didReceiveMemoryWarning" method will be called
// in which case we can recover some memory and keep the app running.
//
self.startStopButton.title = @"Stop";
self.cancelButton.enabled = NO;
self.timedButton.enabled = NO;
self.takePictureButton.enabled = NO;
cameraTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 // fire every 1.5 seconds
target:self
selector:@selector(timedPhotoFire:)
userInfo:[NSNumber numberWithInt:kRepeatingShot]
repeats:YES];
[cameraTimer fire]; // start taking pictures right away
}
}
#pragma mark -
#pragma mark Timer
// gets called by our repettive timer to take a picture
- (void)timedPhotoFire:(NSTimer *)timer
{
[self.imagePickerController takePicture];
NSInteger cameraAction = [self.cameraTimer.userInfo integerValue];
switch (cameraAction)
{
case kOneShot:
{
// timer fired for a delayed single shot
[self.cameraTimer invalidate];
cameraTimer = nil;
[self.tickTimer invalidate];
tickTimer = nil;
break;
}
case kRepeatingShot:
{
// timer fired for a repeating shot
break;
}
}
}
// gets called by our delayed camera shot timer to play a tick noise
- (void)tickFire:(NSTimer *)timer
{
AudioServicesPlaySystemSound(tickSound);
}
#pragma mark -
#pragma mark UIImagePickerControllerDelegate
// this get called when an image has been chosen from the library or taken from the camera
//
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
// give the taken picture to our delegate
if (self.delegate)
[self.delegate didTakePicture:image];
if (![self.cameraTimer isValid])
[self finishAndUpdate];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self.delegate didFinishWithCamera]; // tell our delegate we are finished with the picker
}
@end
Join the conversation! Your thoughts help the community grow.