camera overlay picture - iphone

edit 3
Good news and bad news. The good news is that in the Connections Inspector by disconnecting the overlay UIToolbar and connecting the UIImageview, I see theKing, but then -- the bad news -- I do not see the UIToolbar, which I also need. So the question now is, how can the user get back to the calling VC when s/he is finished here? How can both the toolbar and the image be part of the the overlay, or can the "go back button" toolbar be on the non-overlay view, or something? Or how can I make both the toolbar and the image show on the OverlayViewController?
edit 3
edit 2
setupImagePicker in OverlayViewController.m.
- (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];
}
}
}
edit 2
edit 1
This is the PhotoPicker sample code link.
edit 1
edit 0
Has anyone tried this on an iPhone instead of an iPad? I do not have an iPhone, but I was reading Matt Neuburg's book today where he says UIImagePicker works differently on the 2 devices.
edit 0
I cannot see the image I am attempting to overlay across the camera view in UIImagePicker. No matter how I add the IBOutlet, as a property or not, the image does not show, but the overlayed toolbar shows fine. Why?
OverlayViewController.h with theKing IBOutlet added to Apple's sample code and then commented out for now.
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioServices.h>
#protocol OverlayViewControllerDelegate;
#interface OverlayViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
// IBOutlet UIImageView* theKing; ******** temporarily commented out
id <OverlayViewControllerDelegate> delegate;
}
#property (nonatomic, assign) id <OverlayViewControllerDelegate> delegate;
#property (nonatomic, retain) UIImagePickerController *imagePickerController;
- (void)setupImagePicker:(UIImagePickerControllerSourceType)sourceType;
#end
#protocol OverlayViewControllerDelegate
- (void)didTakePicture:(UIImage *)picture;
- (void)didFinishWithCamera;
#end
OverlayViewController.m with the property for theKing IBOutlet added to Apple's sample code.
#import "OverlayViewController.h"
enum
{
kOneShot, // user wants to take a delayed single shot
kRepeatingShot // user wants to take repeating shots
};
#interface OverlayViewController ( )
#property (assign) SystemSoundID tickSound;
#property (nonatomic, retain) IBOutlet UIImageView* theKing; // added *********
#property (nonatomic, retain) IBOutlet UIBarButtonItem *takePictureButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *startStopButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *timedButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *cancelButton;
#property (nonatomic, retain) NSTimer *tickTimer;
#property (nonatomic, retain) NSTimer *cameraTimer;
I cannot see the image theKing when I execute the code on an iPhone. Below is a view of the nib I have added showing some of the connections made. No errors are thrown, but I cannot see the image, only the UIToolbar already added.

Update
I've updated it now and tried to replicate what you've done in your question. I've included full source of .h/.m and theKing#2x.png. Create a new project and paste the source into the files and add theKing#2x.png. Everything is done programmatically - you don't need to set anything up in interface builder other than embedding your view in a navigation controller.
Here is theKing#2x.png - http://i.imgur.com/0DrM7si.png
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// assign action to button
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
myButton.frame = CGRectMake(0, 0, 200, 60);
myButton.center = self.view.center;
[myButton addTarget:self action:#selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];
[myButton setTitle:#"Image Picker" forState:UIControlStateNormal];
[self.view addSubview:myButton];
}
- (void)buttonPress:(id)sender {
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
// alert the user that the camera can't be accessed
UIAlertView *noCameraAlert = [[UIAlertView alloc] initWithTitle:#"No Camera" message:#"Unable to access the camera!" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[noCameraAlert show];
} else {
// prepare imagePicker view
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
imagePicker.allowsEditing = NO;
imagePicker.showsCameraControls = NO;
// create view for overlay
CGRect overlayRect = CGRectMake(0, 0, imagePicker.view.frame.size.width, imagePicker.view.frame.size.height);
UIView *overlayView = [[UIView alloc] initWithFrame:overlayRect];
// prepare the image to overlay
UIImageView *overlayImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"theKing"]];
overlayImage.center = overlayView.center;
overlayImage.alpha = 0.5;
// prepare toolbar for overlay
UIToolbar *overlayToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 600, overlayView.frame.size.width, 40)];
overlayToolbar.center = CGPointMake(overlayView.center.x, overlayView.frame.size.height - 20);
overlayToolbar.barStyle = UIBarStyleBlack;
UIBarButtonItem *takePictureButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(takePictureButtonPressed:)];
UIBarButtonItem *flexibleBarSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
flexibleBarSpace.width = 1000;
UIBarButtonItem *startStopButton = [[UIBarButtonItem alloc] initWithTitle:#"Snap" style:UIBarButtonItemStyleBordered target:self action:#selector(startStopButtonPressed:)];
UIBarButtonItem *timedButton = [[UIBarButtonItem alloc]initWithTitle:#"Timed" style:UIBarButtonItemStyleBordered target:self action: #selector(timedButtonPressed:)];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action: #selector(cancelButtonPressed:)];
overlayToolbar.items = [NSArray arrayWithObjects:takePictureButton, flexibleBarSpace, startStopButton, timedButton, cancelButton, nil];
[overlayView addSubview:overlayImage];
[overlayView addSubview:overlayToolbar];
// add the image as the overlay
[imagePicker setCameraOverlayView:overlayView];
// display imagePicker
[self.navigationController presentViewController:imagePicker animated:YES completion:nil];
}
}
#pragma mark - UIBarButton Selectors
- (void)takePictureButtonPressed:(id)sender {
NSLog(#"takePictureButtonPressed...");
// TODO: take picture!
}
- (void)startStopButtonPressed:(id)sender {
NSLog(#"startStopButtonPressed...");
// TODO: make this do something
}
- (void)timedButtonPressed:(id)sender {
NSLog(#"timedButtonPressed...");
// TODO: implement timer before calling takePictureButtonPressed
}
- (void)cancelButtonPressed:(id)sender {
NSLog(#"cancelButtonPressed");
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - UIImagePickerController Delegate Methods
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)editingInfo {
// determine if the user selected or took a new photo
UIImage *selectedImage;
if ([editingInfo objectForKey:UIImagePickerControllerOriginalImage]) selectedImage = (UIImage *)[editingInfo objectForKey:UIImagePickerControllerOriginalImage];
else if ([editingInfo objectForKey:UIImagePickerControllerEditedImage]) selectedImage = (UIImage *)[editingInfo objectForKey:UIImagePickerControllerEditedImage];
// TODO: Do something with selectedImage (put it in a UIImageView
// dismiss the imagePicker
[picker.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Screenshot
This is what it looks like when I run it.
Does this satisfy your app requirements?

One answer I have found is to put the image on a huge button which has as an action Done:. I'll have to figure out a way to tell my user to do it, but at least this will dismiss the image view and finish my setup mode. I would really like a cleaner alternative, so please add answers if you have them. Thanks to all who have considered my question.

Related

How to display a UIButton in front of all views in UINavigationController?

I've got a UIButton that I'd like to display in the same position in front of all of the viewControllers of my UINavigationController, much in the same way that a UINavigationBar would - but in this case, I'd like the button to float in the lower-left corner of the screen, like so:
I could try manually adding it to each viewController, but I'd prefer to do it once and forget about it.
Adding the button as a subview to the UIWindow doesn't seem to work - it winds up behind the rootViewController.
Update: I've figured out a way to do it, but because it involves iOS 7, I can't post the solution here until the NDA is lifted. The good news is, it's fairly simple to accomplish this! I'll post something once it's OK to share.
create a NSObject class buttonPanel and allocate the button and you can call the button panel as follow:
buttonPanel * buttonPanel = [[buttonPanel alloc] init];
buttonPanel.delegate = self;
[buttonPanel showButtonWithNavigationController:self.navigationController inView:self.parentViewController.view];
ButtonPanel class:
//ButtonPanel.h
#import <Foundation/Foundation.h>
#class ButtonPanel;
#protocol ButtonPanelDelegate <NSObject>
-(void) ButtonPanel:(ButtonPanel*) buttonPanel ;
#end
#interface ChatMessagePanel : NSObject<UIActionSheetDelegate> {
UINavigationController *navigationController;
id<ButtonPanelDelegate> delegate;
}
#property(nonatomic,retain) UINavigationController *navigationController;
#property (nonatomic,retain) id<ButtonPanelDelegate> delegate;
-(void)showButtonWithNavigationController:(UINavigationController*) navigationController inView:(UIView*) view;
#end
// ButtonPanel.m
#import "ChatMessagePanel.h"
#implementation ButtonPanel
#synthesize userListModal,delegate,navigationController;
-(void)showMessageWithNavigationController:(UINavigationController*) _navigationController inView:(UIView*) view
{
self.navigationController = _navigationController;
baseViewWidth = view.frame.size.width;
baseViewHeight = view.frame.size.height;
incomingRequestActionSheet = [[UIActionSheet alloc] initWithTitle:#"" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
[incomingRequestActionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
[incomingRequestActionSheet showInView:view];
UIButton *blockUserBttn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 40)];
[blockUserBttn setTitle:NSLocalizedString(#"BLOCK_USERS",#"") forState:UIControlStateNormal];
[blockUserBttn setBackgroundColor:[UIColor clearColor]];
[blockUserBttn addTarget:self action:#selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *blockUserBarBttn = [[UIBarButtonItem alloc] initWithCustomView:blockUserBttn];
[optionToolBar setItems:[NSArray arrayWithObjects:blockUserBarBttn, nil]];
[incomingRequestActionSheet addSubview:optionToolBar];
}
-(void)buttonAction:(id) sender
{
}
#end
I don't think this is possible in the ios. You must have to do
individual for all view.
You can simply add the UIButton on the window like
[self.window addSubview:Button];
after self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

touchesBegan not functioning on programmatically created view and imageview

I am programmatically creating a view and a imageview while in viewControllerA for an another viewControllerB before I then goto viewControllerB. I have to do this, as I am using an image from the imagePickerController. However by doing this, touchesBegan does not function in viewControllerB
I have set UserInteractionEnabled to true/yes in both the attributes inspector of the xib and programmatically everywhere!
My xib is just a blank canvas, with one View. I have tried different settings with the connections inspector, but still no luck.
Here is my code.
viewControllerA.m
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
view = [[UIView alloc] initWithFrame:screenRect];
image = [info valueForKey:UIImagePickerControllerEditedImage];
SSViewController *psView = [[SSViewController alloc] initWithNibName:#"SSViewController" bundle:nil];
psView.view = [[UIView alloc] initWithFrame:screenRect];
[psView.view setUserInteractionEnabled:YES];
[picker pushViewController:psView animated:YES];
imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(20, 20, 280, 280);
[imageView setUserInteractionEnabled:YES];
[psView.imageView setUserInteractionEnabled:YES];
[psView.view addSubview:imageView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:psView action:#selector(endPS:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"done" forState:UIControlStateNormal];
button.frame = CGRectMake(140.0, 330.0, 80.0, 25.0);
[psView.view addSubview:button];
}
viewControllerB.h (SSViewController.h)
#interface SSViewController : UIViewController
{
IBOutlet UIImageView *imageView;
IBOutlet UIView *view;
}
#property (nonatomic,strong) IBOutlet UIImageView *imageView;
#property (nonatomic,strong) IBOutlet UIImage *image;
#property (nonatomic, strong) IBOutlet UIView *view;
- (IBAction)endPS:(id)sender;
#end
viewControllerB.m (SSViewController.m)
#implementation SSViewController
#synthesize imageView;
#synthesize image;
#synthesize view;
:
:
- (void)viewDidLoad
{
[view setUserInteractionEnabled:YES];
[imageView setUserInteractionEnabled:YES];
:
:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesBegan");
:
You're doing a number of things wrong:
Don't push a view controller on to the UIImagePickerController. If you've presented it modally, which I hope you have, you need to dismiss it (in viewControllerA) and push your new view controller (viewControllerB) onto your own navigation controller. The fact that you're pushing onto this highly customised navigation controller is most likely why touchesBegan is not being called.
Why are you manually creating the view for viewControllerB? If you're loading it from a XIB file, it will have a perfectly good view ready for you. And don't define the view property in viewControllerB.h, it's already defined in UIViewController.h.
Don't forget to call [super viewDidLoad] in viewControllerB.m. This is a classic mistake that will cause you many headaches.
EDIT:
What I would personally have done is added a method on viewControllerB as such:
viewControllerB.h
#interface SSViewController : UIViewController
{
- (void)setImage:(UIImage *)image;
}
#end
viewControllerB.m
#implementation SSViewController
{
- (void)setImage:(UIImage *)image
{
// In case the image view already exists, remove it first.
[_imageView removeFromSuperview];
_imageView = [[UIImageView alloc] initWithImage:image];
_imageView.frame = CGRectMake(20, 20, 280, 280);
[self.view addSubview:_imageView];
}
}
#end
This way, in viewControllerA.m you can just create viewControllerB.m and call this setImage: method to let viewControllerB do all the work.

Setting up an UIActivityIndicatorView for the UITableViewController programmatically

I have a regular UITableViewController and a UITableView as its only view, and I want to have an UIActivittyIndicatorView in addition to the table view.
So I need a view structure like this:
view (UIView):
tableView
activityIndicatorView
What's the cleanest way to do it without InterfaceBuilder? I guess I need to override the loadView: method, but I haven't succeed doing it so far.
UPDATE for ARC and iOS 5.0+ (I think old version needs to be removed already as we have new, better API's:)):
Add to header .h file of your UIViewController subclass:
#property (nonatomic, weak) UIActivityIndicator *activityIndicator;
And override methods in .m file of your UIViewController subclass:
- (void)loadView {
[super loadView];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
// If you need custom color, use color property
// activityIndicator.color = yourDesirableColor;
[self.view addSubview:activityIndicator];
[activityIndicator startAnimating];
self.activityIndicator = activityIndicator;
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGSize viewBounds = self.view.bounds;
self.activityIndicator.center = CGPointMake(CGRectGetMidX(viewBounds), CGRectGetMidY(viewBounds));
}
=============================================================
non-ARC version, iOS < 5.0:
You should override method
-(void)loadView {
[super loadView];
self.activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
[self.view addSubview:self.activityIndicator];
self.activityIndicator.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
[self.activityIndicator startAnimating];
}
Also, add
#property (nonatomic, assign) UIActivityIndicatorView *activityIndicator;
at the header file
and
#synthesize activityIndicator;
to the .m file

Trying to base some code off of Apple's Image Zooming App example, missing some simple Interface Builder knowledge

I'm trying to base part of my app off of Apple's Image Zooming example, to get zooming, scrolling, and orientation of images that are saved to the app's sandbox.
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/UIScrollView_pg/Introduction/Introduction.html
I have it sort of working now, except that when the ScrollView loads, it's blank. The code looks something like this:
#interface PhotoViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *imageScrollView;
UIImageView *imageView;
}
#property (nonatomic, retain) IBOutlet UIScrollView *imageScrollView;
#property (nonatomic, retain) UIImageView *imageView;
#end
#implementation PhotoViewController
#synthesize imageView, imageScrollView;
- (void)viewDidLoad {
[super viewDidLoad];
imageScrollView.bouncesZoom = YES;
imageScrollView.delegate = self;
imageScrollView.clipsToBounds = YES;
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image1.jpg"]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
imageView.userInteractionEnabled = YES;
[imageScrollView addSubview:imageView];
imageScrollView.contentSize = [imageView frame].size;
}
The xib has a Photo View Controller->Scroll View->View structure. I have a feeling this is where the problem is. I tried to hook up all the outlets identically to the example, but under Referencing Outlets the example has a viewController hooked up to the ImageZoomingAppDelegate. Since my PhotoViewController is a subview, there's not a place to hook up the viewController like that.
Here's how I bring up the PhotoViewController:
(IBAction) photoButtonPressed: (id) sender {
viewController = [[PhotoViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
I know I must be just "this close" to having it all hooked up right, but I don't understand the relationship of the xib to the code well enough to know how to debug it. I'm not even sure if I know enough to ask the right questions.
Try changing viewController = [[PhotoViewController alloc] init]; to
viewController = [[PhotoViewController alloc] initWithNibName:#"PhotoViewController" bundle:nil];
(of course change the text string to whatever you called your xib file).

UITabBarController rotation problem with popViewControllerAnimated and selectedIndex (iPhone SDK)

This is a very important auto rotate issue and easy to reproduce.
My application has a UITabBarController. Each tab is a UINavigationController. Auto rotation is handled with normal calls to shouldAutorotateToInterfaceOrientation and didRotateFromInterfaceOrientation.
The interface rotates normally until I call UIViewController.popViewControllerAnimated and change UITabBarController.selectedIndex.
Steps to reproduce:
Create a demo Tab Bar Application.
Add the following code to the App Delegate .h file:#import <UIKit/UIKit.h>
#interface TestRotationAppDelegate : NSObject {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
// Redefine the interface to cach rotation messages
#interface UITabBarController (TestRotation1AppDelegate)
#end
Add the following code to the App Delegate .m file:#import "TestRotationAppDelegate.h"
#implementation TestRotationAppDelegate
#synthesize window;
#synthesize tabBarController;
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(void)dealloc {
[tabBarController release];
[window release];
[super dealloc];
}
#end
#implementation UITabBarController (TestRotation1AppDelegate)
-(void)viewDidLoad {
[super viewDidLoad];
// Add a third tab and push a view
UIViewController *view1 = [[[UIViewController alloc] init] autorelease];
view1.title = #"Third";
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:view1] autorelease];
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObjectsFromArray:self.viewControllers];
[array addObject:nav];
self.viewControllers = array;
// Push view2 inside the third tab
UIViewController *view2 = [[[UIViewController alloc] init] autorelease];
[nav pushViewController:view2 animated:YES];
// Create a button to pop view2
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(50, 50, 220, 38);
[button setTitle:#"Pop this view" forState:UIControlStateNormal];
[button addTarget:self action:#selector(doAction) forControlEvents:UIControlEventTouchUpInside];
[view2.view addSubview:button];
}
-(void) doAction {
// ROTATION PROBLEM BEGINS HERE
// Remove one line of code and the problem doesn't occur.
[self.selectedViewController popViewControllerAnimated:YES];
self.selectedIndex = 0;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
The interface auto rotates normally until you tap the button on tab #3.
Your help will be geatly appreciated!
iPhone SDK 3.2 solves this issue.
With previous SDK use [self.selectedViewController popViewControllerAnimated:NO].