I created a camera button in a collection view controller cell to take a picture, and output it to a UIImageView the size of the cell. Right now I'm getting a error with the delegate and I'm not quite sure what it wants me to do.
- (IBAction)cameraButtonClicked:(id)sender {
if (![UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
UIAlertView *cameraAlertView = [[UIAlertView alloc] initWithTitle:#"Camera Not Available" message:#"There is no camera on this device which really defeats the purpose of this game. We suggest you get an iDevice with a camera." delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[cameraAlertView show];
}else{
//Show the Image Picker Controller Here
UIImagePickerController * ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
ipc.allowsEditing = NO;
//Set the Delegate
ipc.delegate = self;
[self.navigationController presentViewController:ipc animated:YES completion:nil];
}
}
It's telling you that self does not conform to the UINavigationControllerDelegate and/or UIImagePickerControllerDelegate protocols. Implement those protocols on your class.
Did you specify the UIImagePickerControllerDelegate protocol in your header?
Related
I'm looking to use a UIActionSheet kind of like a contextual message box (with no action buttons at all and just a label in the bubble with an arrow pointing at something). Since there are no actions the user can take, I would like it to not require a tap to dismiss, but I can't see any way (such as a passthroughViews property) to allow this.
It's probably not designed for this, but it does happen to be handy for it.
This is some example code of how to show an UIAlertView and dismiss it automatically.
Show it:
- (void)show
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"title"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
alert.tag = tag;
[alert show];
}
Dismiss it:
- (void)dismiss
{
for (UIWindow* w in [UIApplication sharedApplication].windows)
for (NSObject* o in w.subviews)
if ([o isKindOfClass:[UIAlertView class]]) {
UIAlertView *alert = (UIAlertView*) o;
if (alert.tag == tag)
[alert dismissWithClickedButtonIndex:[(UIAlertView*)o cancelButtonIndex] animated:YES];
}
}
Yo can call the dismiss method after a couple of seconds:
[self performSelector:#selector(dismiss) withObject:nil afterDelay:1.0 inModes:nil];
I am trying to take a screenshot and email it using the mail composer. Everything works great except the mail composer won't dismiss. This post seems to have the same problem, but the solution provided did not work for me. Can't dismiss the email composer view in iPhone?
- (IBAction)Email:(id)sender {
UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * imageData = UIImageJPEGRepresentation(image, 1.0);
if ( [MFMailComposeViewController canSendMail] ) {
MFMailComposeViewController * mailComposer = [[[MFMailComposeViewController alloc] init] autorelease];
mailComposer.delegate = self;
[mailComposer setSubject:#"Risk Assessment"];
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpg"];
[self presentModalViewController:mailComposer animated:YES];
}
}
The above code works great. How do I call this bottom portion. It seems like the compiler just skips past it.
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
if (error){
NSString *errorTitle = #"Mail Error";
NSString *errorDescription = [error localizedDescription];
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:errorTitle message:errorDescription delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[errorView show];
[errorView release];
}
[controller dismissModalViewControllerAnimated:YES];
}
Thanks in advance.
Try
mailComposer.mailComposeDelegate = self;
instead of
mailComposer.delegate = self;
From the MFMailComposeViewController documentation:
#property(nonatomic,assign) id<MFMailComposeViewControllerDelegate> mailComposeDelegate;
The delegate object is responsible for dismissing the view presented by this view controller at the appropriate time. Therefore, you should always provide a delegate and that object should implement the methods of the MFMailComposeViewControllerDelegate protocol.
I am pretty sure that last line should be
[self dismissModalViewControllerAnimated:YES];
The ViewController that presented the view modally, also dismisses it.
I am currently developing an application which needs an option to 'share' using multiple services; such as email, twitter.
To to this, I have a UIBarButtonItem coded in and when touched, it triggers this:
UIActionSheet *sheet = [[UIActionSheet alloc]
initWithTitle:#""
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[sheet addButtonWithTitle:#"Email"];
[sheet addButtonWithTitle:#"Tweet"];
[sheet addButtonWithTitle:#"Cancel"];
sheet.cancelButtonIndex = sheet.numberOfButtons-1;
[sheet showFromRect:self.view.bounds inView:self.view animated:YES];
[sheet release];
In conjunction with this to detect which button is selected:
clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == actionSheet.cancelButtonIndex) { return; }
switch (buttonIndex) {
case 0:
{
[self emailThis];
break;
}
case 1:
{
[self tweetThis];
break;
}
}
This works a treat on the iPhone. But unfortunately it displays incorrectly on the iPad. It looks like it is trying to display the UIPopoverController, but it is positioned center of the navbar with practically no height.
I have looked into using the UIPopoverController, but I cannot seem to find out how to use it with buttons. Is there anyway I can adapt the code above to properly display the buttons, as it's trying to already.
Many thanks,
Ryan
PS: I'm new to objective-c/iOS coding, so please be specific. Thank you :)
EDIT:
I have tried using:
[sheet showFromBarButtonItem:[self share] animated:YES];
But it doesn't work. Here is my code for the button:
UIBarButtonItem *share = [[UIBarButtonItem alloc]
initWithTitle:#"Share"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(loadShare)];
self.navigationItem.rightBarButtonItem = share;
[share release];
Also here is the code in the .h file:
#interface DetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UIBarButtonItem *share;
}
#property (nonatomic, retain) IBOutlet UIBarButtonItem *share;
Here is the debug error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray
initWithObjects:count:]: attempt to insert nil object from objects[0]'
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(actionPhotoShare:)] autorelease];
...
-(void)actionPhotoShare:(id)sender
{
actionSheetShare = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:NSLocalizedString(#"ActionSheet_Cancel", #"")
otherButtonTitles:NSLocalizedString(#"ActionSheet_Email", #""),nil];
if (IS_DEVICE_IPAD) {
[actionSheetShare showFromBarButtonItem:sender animated:YES];
}else {
[actionSheetShare showInView:self.view];
}
}
Instead of [sheet showFromRect], use [sheet showFromBarButtonItem], and point it to your Share UIBarButtonItem.
Note: you may need to create an IBOutlet or ivar for your UIBarButtonItem if you don't have one already, but that's extremely simple and I'm guessing you can do that.
Your issue is that you are using showFromRect with the rect being the entire screen. That means the popup is placing the "arrow" the best it can to center on the screen. What you want is either showFromBarButtonItem or pass in the rect (self.shareButtonItem.frame) of the button.
I'm trying to integrate sending mail into my app, but I end up with 2 warnings. I am using Obj-C, the Cocos2d Framework. This is my code.
-(void) mailTapped: (id) sender {
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]) {
[composer setToRecipients:[NSArray arrayWithObjects:#"", nil]];
[composer setSubject:#"Check Out This Awesome App!"];
[composer setMessageBody:#"I found this great game on the App Store! It's called Mole Attack. It's a side scroller with an epic story. You can check out some screenshots of the gameplay and download it here. Download link - " isHTML:NO]; //Include link and pics
[self presentModalViewController:composer animated:YES]; // <--- warning - GameOver (name of class) may not respond to '-presentModalViewController:animated:'
}
}
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES]; // <--- warning - GameOver may not respond to '-dismissModalViewControllerAnimated:YES'
if (result == MFMailComposeResultFailed) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failed" message:#"The email was not sent. You must be in wifi or 3G range. Try again later." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
Thanks in advance!
Are you sure your GameOver class is inheriting from UIViewController? That's the class that defines the two methods that you're getting warnings about.
After I choose a picture through the UIImagePickerController interface from the Photo Library, the Photo Library view stays displayed, even though I've called dismissModelViewControllerAnimated in imagePickerController:didFinishPickingImage:editingInfo.
Has anyone seen this? These are the three relevant methods I'm using:
- (IBAction)choosePictureFromLibrary:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsImageEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}
else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error accessing Photo Library" message:#"This device does not support a Photo Library." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Picture picked!" message:#"You picked a picture!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker {
[picker dismissModalViewControllerAnimated:YES];
}
I would have thought that calling imagePickerController:didFinishPickingImage:editingInfo would completely dismiss the Photo Library view, but it doesn't seem to. Is there anything else I have to do to make it go away?
You need to access the viewController of the picker not the picker itself. Try this line instead.
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
You can just call
[self dismissModalViewControllerAnimated:YES];
to dismiss any modal view controller on top of the current view.
This makes sense since you present the view controller by calling:
[self presentModalViewController:picker animated:YES];
Just an update to the answers to this
[self dismissModalViewControllerAnimated:YES];
has been deprecated in iOS 6.0 so you now need to use.
[self dismissViewControllerAnimated:YES completion:nil];
Not a huge change but for anyone that looks at this question and they are using iOS 6.0 they will need an updated answer.
[self presentModalViewController:filePicker animated:YES];
has also been deprecated in favor of
[self presentViewController:filePicker animated:YES completion:nil];