How do I display a UIAlertView at the time I call it? - ios

So, similar to this question:
UIAlertView taking time to show
I'm running into a problem where my UIAlertView is not displaying until after all of my other code has run.
I have tried using the
dispatch_async(dispatch_get_main_queue(),^{
[self presentLoadingAlertWithTitle:NSLocalizedString(#"Creating Account...", nil)];
});
But I was unable to get it to change what happens. Currently, a user clicks a button and it triggers createAccountButtonReleased. Then it seems to skip over the dispatch_async part, run the rest of the code, and then come back to it.
- (IBAction)createAccountButtonReleased:(id)sender {
dispatch_async(dispatch_get_main_queue(),^{
[self presentLoadingAlertWithTitle:NSLocalizedString(#"Creating Account...", nil)];
});
if ((![self.firstNameTextField hasText] && ![self.lastNameTextField hasText]) || ![self.emailTextField hasText] || ![self.passwordTextField hasText]) {
[self dismissAlert:^(void){ [self presentOkAlertWithTitle:NSLocalizedString(#"An error has occured.", nil) andMessage:NSLocalizedString(#"All text fields should be filled out.", nil)];}];
}
else if (([self.firstNameTextField hasText] || [self.lastNameTextField hasText]) && [self.emailTextField hasText] && [self.passwordTextField hasText]) {
UserCreateWebService *ucws = [[UserCreateWebService alloc]initWithFirstName:self.firstNameTextField.text andLastName:self.lastNameTextField.text andEmail:self.emailTextField.text andPassword:self.passwordTextField.text];
NSString *ucwsResponse = [ucws userCreated];
if ([ucwsResponse isEqualToString:#"Contact already exists"]) {
[self dismissAlert:^(void){[self presentOkAlertWithTitle:NSLocalizedString(#"An error has occured.", nil) andMessage:NSLocalizedString(#"A contact with that information already exists. Please enter a different email and try again.", nil)];}];
}
else if (ucwsResponse.length > 75 && [[ucwsResponse substringToIndex:75] isEqualToString:#"EX: The specified string is not in the form required for an e-mail address."]) {
[self dismissAlert:^(void){ [self presentOkAlertWithTitle:NSLocalizedString(#"An error has occured.", nil) andMessage:NSLocalizedString(#"The entered email is not in the required format. Please enter as:\"username#domain.com\"", #"Replace username with the equivalent word and domain with the equivalent word")];}];
}
else if ([ucwsResponse isEqualToString:#"True"]) {
//logs in the newly created user
User *user = [[[UserLoginService alloc]initWithUsername:self.emailTextField.text andPassword:self.passwordTextField.text] attemptLogin];
if (!user) {
[self dismissAlert:^(void){[self presentOkAlertWithTitle:NSLocalizedString(#"Something went wrong.", nil) andMessage:NSLocalizedString(#"Please ensure that you have an internet connection.", nil)];}];
}
else {
//post a notification
}
[self dismissAlert];
UIAlertView *success = [[UIAlertView alloc]initWithTitle:NSLocalizedString(#"Registration Complete", nil) message:NSLocalizedString(#"Welcome! Press the Ok button to get started!" , nil) delegate:self cancelButtonTitle:NSLocalizedString(#"Ok", nil) otherButtonTitles:nil, nil]; // Makes Alert View
[success show]; //shows alert view
}
else { //need to beef up the error message with the return from the json.
[self presentOkAlertWithTitle:NSLocalizedString(#"An error has occured.", nil) andMessage:NSLocalizedString(#"Your account has not been created. Please check your internet connection or try again later.", nil)];
}
}
presentLoadingAlertWithTitle:
- (void)presentLoadingAlertWithTitle:(NSString *)title completion:(void (^)(void))completion
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:#"\n" preferredStyle:UIAlertControllerStyleAlert];
CGRect activityIndicatorFrame = alertController.view.bounds;
activityIndicatorFrame.size.height -= 35.0f;
activityIndicatorFrame.origin.y += 35.0f;
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:activityIndicatorFrame];
[activityIndicator setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
[activityIndicator setUserInteractionEnabled:NO];
[activityIndicator startAnimating];
[alertController.view addSubview:activityIndicator];
[self presentViewController:alertController animated:YES completion:completion];
}
- (void)presentLoadingAlertWithTitle:(NSString *)title
{
[self presentLoadingAlertWithTitle:title completion:nil];
}
Any advice?

Related

UIActivityIndicatorView not working right

I have the following initialization in viewDidLoad:
self.indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[self.indicator setCenter:CGPointMake([[UIScreen mainScreen]bounds].size.width/2, [[UIScreen mainScreen]bounds].size.height/2)];
//self.indicator.hidden = YES;
[self.indicator setHidesWhenStopped:1];
self.indicator.color = [UIColor orangeColor];
self.indicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
Now if I add the following 2 lines, the indicator shows and spins:
[self.view addSubview:self.indicator];
//self.indicator.hidden = NO;
[self.indicator startAnimating];
Thats not what I want, because the indicator should first show when I call my method, lets call it pressButton. I would then do the following:
- (void)pressButton {
[self.view addSubview:self.indicator];
[self.indicator startAnimating];
dispatch_async(dispatch_get_main_queue(), ^{
WebAccess *web = [WebAccess new];
NSDictionary *dicResults = [web logon:self.email.text :self.password.text];
if([[dicResults valueForKey:#"StatusCode"] intValue] == 200){// ALL IS OK
appDelegate.accessToken = [dicResults valueForKey:#"AccessToken"];
dicResults = [web getAccount:appDelegate.accessToken];
NSLog(#"dicResults after getaccount: %#", dicResults);
if([[dicResults valueForKey:#"StatusCode"] intValue] == 200){//dicResults holds a new object now!
NSArray *usersArray = [dicResults valueForKeyPath:#"Account.Users"];
NSLog(#"usersArray: %#", usersArray);//CORRECT DATA RECEIVED: YES
if(usersArray.count){
[[appDelegate cdh]deleteAllFromEntityWithName:#"AccountData"];
[[appDelegate cdh]deleteAllFromEntityWithName:#"UserData"];//------------- REMOVE ALL WHEN LOADING NEW USER. AMYBE TOO QF. CHECK WITH DESIGNER
}else{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"No users found on this account!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
//more code........
appDelegate.users = [NSMutableArray arrayWithArray:[[appDelegate cdh] fetchUsers]];
if(appDelegate.users.count){
NSArray *currentUserArray = [NSArray arrayWithArray:[[appDelegate cdh]fetchCurrentUser]];
appDelegate.currentUser = [currentUserArray lastObject];
if(appDelegate.currentUser==nil)
appDelegate.currentUser = appDelegate.users[0];
}
[menu goToVC:1];
}
}else if([[dicResults valueForKey:#"StatusCode"] intValue] == 201){
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Wrong email or password!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
[self.indicator stopAnimating];
});
}
I could've sworn I had it working yesterday when testing, but now it doesn't. Whats weird is if i put those same two lines from my press button method into viewdidload, the indicator shows, but when I do it inside my method (but obv outside the dispatch) it never shows....
Any help appreciated
Spin your long running process off onto its own thread. Leave the main thread open for UI updates.
- (void)pressButton
{
[self.view addSubview:self.indicator];
[self.indicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Code for your long running process to run in the background...
// Stop your activity indicator back on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.indicator stopAnimating];
});
});
}

How to show a new view controller if the alert is validated? (objective c)

instead of a button i'd like to change the view controller if a alert is validated but i've no idea how to do is. I use a cocoa pod for the notification (just cause the design is beautiful). every answer is welcome!
- (IBAction)changeTheme:(UIButton *)sender {
// for changing view controller
[UIView animateKeyframesWithDuration:1.0 delay:0 options:0 animations:^{
changeTheme.transform = CGAffineTransformMakeScale(2, 2);
} completion:^(BOOL finished) {
// init alert with options
SCLAlertView *changeThemeNotification = [[SCLAlertView alloc] init];
// to sport
[changeThemeNotification addButton:#"change to sport" validationBlock:^BOOL{
BOOL passedValidation = true;
return passedValidation;
} actionBlock:^{
}];
// to food
[changeThemeNotification addButton:#"change to food" validationBlock:^BOOL{
BOOL passedValidation = true;
return passedValidation;
} actionBlock:^{
[self.view setBackgroundColor:[UIColor blackColor]];
}];
// to animal
[changeThemeNotification addButton:#"change to animal" validationBlock:^BOOL{
BOOL passedValidation = true;
return passedValidation;
} actionBlock:^{
[self.view setBackgroundColor:[UIColor greenColor]];
}];
// else (message & options)
[changeThemeNotification showCustom:self image:nil color:[self.colorWheel randomColor] title:#"Test" subTitle:#"This is a test notification for the navigation." closeButtonTitle:#"stay" duration:0.0f];
changeThemeNotification.hideAnimationType = SlideOutToBottom;
changeThemeNotification.shouldDismissOnTapOutside = YES;
changeThemeNotification.soundURL = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/url_to_sound.mp3", [[NSBundle mainBundle] resourcePath]]];
}];
}
try this
SCLAlertView *changeThemeNotification = [[SCLAlertView alloc] init];
[changeThemeNotification addButton:#"change to sport" validationBlock:^BOOL{
BOOL passedValidation = true;
return passedValidation;
} actionBlock:^{
[self performSegueWithIdentifier:#"yourSegueName" sender:self];
}];
The following code will help:
To check the iOS version:
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
To display the alert view:
if(SYSTEM_VERSION_LESS_THAN(#"8.0"))
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#""
message:#"your message"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alert show];
}
else
{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:#""
message:#"You message..."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"OK", #"OK action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
[self performSegueWithIdentifier:#"yourSegueName" sender:self];
}];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}
Also use the following code to handle "ok" button for iOS <8.0.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
{
[self performSegueWithIdentifier:#"yourSegueName" sender:self];
}
else
{
}
}

UIAlertView not calling

I'm attempting to create a simple webpage browser-esque application, where whenever the user wants to use a back, home, or forward function they are asked through an alert view to confirm.
The console window confirms that it has no problem calling the IBAction but comes up blank whenever I expect it to call Alert View.
Any help would be appreciated.
- (IBAction)controlPanelActions:(id)sender{
if (_controlPanel.selectedSegmentIndex == 0)
{
if ([_viewWeb canGoBack])
{
[self askToGoHome:nil];
}
}
- (IBAction)askToGoHome:(id)sender {
UIAlertView *alertDialog;
alertDialog.tag = 2;
alertDialog = [[UIAlertView alloc]
initWithTitle: #"Confirm"
message:#"Continue with Home Action?"
delegate: self
cancelButtonTitle: #"Yes"
otherButtonTitles: #"No", nil];
[alertDialog show];
}
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if (alertView.tag == 1)
{
if ([buttonTitle isEqualToString:#"Yes"])
{
NSLog(#"back - yes");
[_viewWeb goBack];
}
}
if (alertView.tag == 2)
{
NSLog(#"home - pre-yes");
if ([buttonTitle isEqualToString:#"Yes"])
{
NSLog(#"home - yes");
HOMEPAGEURL = [[NSURL alloc] initWithString:HOMEPAGE];
[self.viewWeb loadRequest:[NSURLRequest requestWithURL:HOMEPAGEURL]];
}
}
if (alertView.tag == 3)
{
if ([buttonTitle isEqualToString:#"Yes"])
{
[_viewWeb goForward];
}
}
}
You set alertDialog.tag = 2;before you call init.
So,everytime you set tag,you set tag to a nil.It will not work.
Alertview alloc and init method sets its tag to 0.
So alertDialog.tag = 2;
will not work.
add this line after alloc and init method.

UIImagePickerController not presenting in iOS 8

Is anyone else having an issue with UIImagePickerController in iOS 8? The method below works perfectly well in iOS 7 on an iPad, but I get the following error when I run this in XCode 6 (Beta 3 or 4) when I try to present the picker (last line). If it matters, the selection of the sourceType is coming from an alertView that is presented in the same place.
Warning: Attempt to present <UIImagePickerController: 0x7c0ae400> on <CAGUCreateContactViewController: 0x7bf61a00> which is already presenting (null)
Method to open imagePicker.
- (void)openPhotoPicker:(UIImagePickerControllerSourceType)sourceType
{
if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType];
if ([availableMediaTypes containsObject:(NSString *)kUTTypeImage]) {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
imagePickerController.sourceType = sourceType;
imagePickerController.mediaTypes = #[(NSString *)kUTTypeImage];
imagePickerController.delegate = self;
self.imagePickerController = imagePickerController;
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
[self presentViewController:self.imagePickerController animated:YES completion:nil];
} else {
if (self.popoverVC) {
[self.popoverVC dismissPopoverAnimated:YES];
self.popoverVC = nil;
}
self.popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
[self.popoverVC presentPopoverFromRect:self.nameAndPicCell.picture.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
}
}
}
I think this is because in iOS 8, alert views and action sheets are actually presented view controllers (UIAlertController). So, if you're presenting a new view controller in response to an action from the UIAlertView, it's being presented while the UIAlertController is being dismissed. I worked around this by delaying the presentation of the UIImagePickerController until the next iteration of the runloop, by doing this:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self openPhotoPicker:sourceType];
}];
However, the proper way to fix this is to use the new UIAlertController API on iOS 8 (i.e. use if ([UIAlertController class]) ... to test for it). This is just a workaround if you can't use the new API yet.
I agree with Ben Lings issue detection. I would suggest a simpler solution in case when using UIActionSheet. I simply moved my code that reacts on Action Sheet selection from:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
{
// my code
}
into:
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation
{
// my code
}
This way app is guarantied that code will be executed AFTER UIActionSheet animation finishes.
Since UIAlertView has similar delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation
{
// my code
}
I suppose that similar solution may apply.
Here is a solution that worked for me
if([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self presentViewController:cameraUI animated:NO completion:nil];
}];
}
else{
[controller presentViewController:cameraUI animated:NO completion:nil];
}
Remember to alloc cameraUI
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
Build and Go!
I was facing the same problem in iOS 8.
Then I saw the change log of the latest update to iOS i.e. 8.0.2 on the device.
It is mentioned in this update that_
"Fixes an issue that prevented some apps from accessing photos from Photo Library"
So test your app using XCode 6 on device with iOS 8.0.2 version it will work fine
Don't test it on iOS 8.0 simulator.
This helped me, hope the same for you.
UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init];
[imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
// image picker needs a delegate so we can respond to its messages
[imagePickerController setDelegate:self];
self.shouldCallViewWillAppear = NO;
if(IS_IOS8)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Place image picker on the screen
[self presentViewController:imagePickerController animated:YES completion:nil];
}];
}
else
{
[self presentViewController:imagePickerController animated:YES completion:nil];
}
You can dismiss the presented view controller (if any) by using
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
This worked for me.
All you need to do is dismiss already presented ViewController:
if (self.presentedViewController) {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}
[self openPhotoPicker:sourceType];
If it still produces error, put openPhotoPicker: to completion handler
I simply did this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
(unsigned long)NULL), ^(void) {
[self retractActivePopover];
dispatch_async(dispatch_get_main_queue(), ^ {
_activePopover=imagePickerPopover;
UIBarButtonItem *callingButton = (UIBarButtonItem*) sender;
[imagePickerPopover presentPopoverFromBarButtonItem:callingButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
});
});
On iOS 8 you should use the new API:
if (SYSTEM_VERSION_IOS_8) {
self.imagePickerController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popPC = self.imagePickerController.popoverPresentationController;
popPC.barButtonItem = self.popoverItem;
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:self.imagePickerController animated:YES completion:nil]
}
I recommend you watch the 2014 WWDC session 228 a look in side presentation controllers
I went through a lot of pain coming up with a solution which works on both iPad and iPhone, this is the final code which some of it comes from comments of other people:
the code has some bugs but it's a very good place to start :)
definitions :
__weak IBOutlet UIButton *attachButton;
UIImage *image;
button's action :
- (IBAction)doAttach:(id)sender {
UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:#"Select image from" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"From library",#"From camera", nil] ;
[action showInView:self.view];
}
#pragma mark - ActionSheet delegates
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if( buttonIndex == 1 ) {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(authStatus == AVAuthorizationStatusAuthorized)
{
NSLog(#"%#", #"You have camera access");
}
else if(authStatus == AVAuthorizationStatusDenied)
{
NSLog(#"%#", #"Denied camera access");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){
NSLog(#"Granted access to %#", AVMediaTypeVideo);
} else {
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“no camera access“
message: #“if you need to use camera in this application go to settings -> appName -> and turn on camera.”
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#“ok” style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
NSLog(#"Not granted access to %#", AVMediaTypeVideo);
return ;
}
}];
}
else if(authStatus == AVAuthorizationStatusRestricted)
{
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“no camera access“
message: #“if you need to use camera in this application go to settings -> appName -> and turn on camera.”
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#“ok” style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
NSLog(#"%#", #"Restricted, normally won't happen");
}
else if(authStatus == AVAuthorizationStatusNotDetermined)
{
NSLog(#"%#", #"Camera access not determined. Ask for permission.");
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){
NSLog(#"Granted access to %#", AVMediaTypeVideo);
} else {
NSLog(#"Not granted access to %#", AVMediaTypeVideo);
return ;
}
}];
}
else
{
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“No camera access“
message: #“error accusing camera”
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#“ok” style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
return;
//NSLog(#"%#", #"Camera access unknown error.");
}
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController *pickerView =[[UIImagePickerController alloc]init];
pickerView.allowsEditing = YES;
pickerView.delegate = self;
pickerView.sourceType = UIImagePickerControllerSourceTypeCamera;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
[ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ];
pickerView.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popPC = pickerView.popoverPresentationController;
popPC.sourceView = attachButton;
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:pickerView animated:YES completion:nil];
} else {
[self presentModalViewController:pickerView animated:YES ];
}
}
}else if( buttonIndex == 0 ) {
ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];
switch (status) {
case ALAuthorizationStatusRestricted:
case ALAuthorizationStatusDenied:
{
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#“no access to library”
message: #“if you wish to access photos in this app go to settings -> appName-> and turn on photos .”
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#“ok” style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
break;
default:
{
UIImagePickerController *pickerView = [[UIImagePickerController alloc] init];
pickerView.allowsEditing = YES;
pickerView.delegate = self;
[pickerView setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
[ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ];
pickerView.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popup = pickerView.popoverPresentationController;
popup.sourceView = attachButton;
popup.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:pickerView animated:YES completion:nil];
} else {
[self presentModalViewController:pickerView animated:YES ];
}
}
break;
}
}
}
#pragma mark - PickerDelegates
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissModalViewControllerAnimated:true];
UIImage * img = [info valueForKey:UIImagePickerControllerEditedImage];
image = img;
}
performSelector:withObject:afterDelay solved my problem.
also didDismissWithButtonIndex do the trick.
Max
Here's a Xamarin solution. What worked for me was to add my actions to a Dismissed event handler.
this.btnPhoto.TouchUpInside += (sender, e) =>
{
actionSheet = new UIActionSheet ("Add Photo");
actionSheet.AddButton ("Take Photo");
actionSheet.AddButton ("Select from Library");
actionSheet.AddButton ("Cancel");
actionSheet.DestructiveButtonIndex = -1; // red
actionSheet.CancelButtonIndex = 3; // black
actionSheet.Clicked += delegate(object a, UIButtonEventArgs b)
{
actionSheet.Dismissed += (object aSender, UIButtonEventArgs dismissArgs) =>
{
switch (dismissArgs.ButtonIndex)
{
case 0:
showCamera ();
break;
case 1:
showPhotoLibrary ();
break;
}
};
};
actionSheet.ShowInView (view);
};

MBProgressHUD after selecting image in UIImagePickerController

I'm selecting an image in UIImagePickerController.
After the image was selected I'm firing another UIActionSheet to select from
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
_selected_image = info[UIImagePickerControllerEditedImage];
UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:#"" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:
#"Share this photo",
nil];
popup.tag = 2;
[popup showInView:[UIApplication sharedApplication].keyWindow];
}
When the user selects "Share" a long process is starting.
I want the MBProgressHUD to show during the process. I can't get progress HUD to show before stuff are starting to happen.
Tried two things:
- (void)actionSheet:(UIActionSheet *)popup clickedButtonAtIndex:(NSInteger)buttonIndex {
if (popup.tag == 1)
{
...
}
else if (popup.tag == 2)
{
if (buttonIndex == 1) //cancel
{
_selected_image = nil;
}
else if (buttonIndex == 0)
{
[imagePicker dismissViewControllerAnimated:YES completion:NULL];
[self doSharePhoto];
return;
}
[imagePicker dismissViewControllerAnimated:YES completion:NULL];
}
}
doSharePhotos start running when the imagePicker is still showing.
Tried:
- (void)actionSheet:(UIActionSheet *)popup clickedButtonAtIndex:(NSInteger)buttonIndex {
if (popup.tag == 1)
{
}
else if (popup.tag == 2)
{
if (buttonIndex == 1) //cancel
{
_selected_image = nil;
}
else if (buttonIndex == 0)
{
[imagePicker dismissViewControllerAnimated:YES completion:^{
[self doSharePhoto];
}];
return;
}
[imagePicker dismissViewControllerAnimated:YES completion:NULL];
}
}
and in this case the MBProgressHUD inside doSharePhoto doesn't apprear at all
** EDIT **:
The code that starts the HUD is in [self doSharePhoto]:
- (void)doSharePhoto {
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
HUD.labelText = #"Please wait...";
HUD.delegate = self;
...
}
Any thoughts?
Does your doSharePhoto method perform the long running operation inside a seperate thread? If not it's blocking the main thread so , MBProgressHUD doesn't get a chance to show. Your doSharePhoto must look like this,
- (void)doSharePhoto {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// Do the long running operation here...
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
});
});
}
EDIT: Problem might be with the view you add your HUD to,
Change
self.navigationController.view to
self.navigationController.visibleViewController.view
So,
[MBProgressHUD hideHUDForView:self.navigationController.visibleViewController.view animated:YES];

Resources