(iOS7, xCode 5.1) I have an app that accesses the Calendar for various purposes, and I'm trying to get all of my error messaging in place.
I have 2 UIAlertviews. Both UIAlertviews show when I need them to, but I only get a call to didDismissWIthButtonIndex for one of them. The alertview called _iCloudAlert is the one that works.
If I show the _iCloudAlert, I get a call to didDismissWIthButtonIndex when a button is clicked, but when I show _deniedAccessAlert I get no call at all. I can't even see the outermost NSLog/s.
I have <UIAlertviewDelegate> in my .h file.
Code that shows the alerts, depending on Calendar access:
// Check the authorization status of our application for Calendar
-(void)checkEventStoreAccessForCalendar
{
NSLog(#"Check Status");
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
// Update our UI if the user has granted access to their Calendar
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
NSLog(#"Already granted");
break;
// Prompt the user for access to Calendar if there is no definitive answer
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
// Display a message if the user has denied or restricted access to Calendar
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
NSLog(#"already denied");
[self performSelectorOnMainThread:#selector(showDeniedAccessAlert) withObject:nil waitUntilDone:NO];
}
break;
default:
break;
}
}
Both alert view methods:
- (void)informUserAboutCloud {
_iCloudAlert = [[UIAlertView alloc]
initWithTitle: #"Important!"
message: #"If you have an iCloud account.....blah, blah, blah..."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[_iCloudAlert show];
}
- (void)showDeniedAccessAlert {
NSLog(#"Show Denied Access Alert");
_deniedAccessAlert = [[UIAlertView alloc]
initWithTitle: #"Attention!"
message: #"It looks like you've blocked access to Calendar data... Blah, Blah, Blah..."
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[_deniedAccessAlert show];
}
And here is the code used to take action on the button clicks:
- (void)alertView:(UIAlertView *)alert didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSLog(#"button index: %i", buttonIndex); //only logs when _iCloudAlert is shown
NSLog(#"alertview: %#", alert); //only logs when _iCloudAlert is shown
if (_iCloudAlert) {
[self checkEventStoreAccessForCalendar];
NSLog(#"check for calendar access from dismissed icloud alert...");
}
if (_deniedAccessAlert) {
NSLog(#"dismissed denied access..."); //never logged
}
}
The 2nd UIAlertView has its delegate set to nil. Change that, and it will work!
Related
See this GIF
And this is the code
-(void)goGuestInfo
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[#"label.change" localize]
message:#"d"
delegate:self
cancelButtonTitle:[#"label.cancel" localize]
otherButtonTitles:[#"label.name" localize],
[#"label.email" localize],
[#"label.phone" localize], nil];
[alertView show];
}
#pragma mark - Alertview delegate
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0: break;
case 1: [self performSegueWithIdentifier:HotelBookingGuestEditNameSegue sender:nil]; break;
case 2: [self performSegueWithIdentifier:HotelBookingGuestEditEmailSegue sender:nil]; break;
case 3: [self performSegueWithIdentifier:HotelBookingGuestEditPhoneSegue sender:nil]; break;
default: break;
}
}
It only does it when I press "name" (i.e. case 1:).
I have never experienced this before and I've used alertviews many many times. Am i missing something obvious? After I go back to the app it will do the segues as it should.
Somewhere deep down in the #imports there was/is a didClickButtonAtIndex that made a phone call.
I am developing an app that allows users to take pictures and send them by mail (xcode version 5.1.1). After the mail is sent, a confirmation message pops up:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error{
switch (result)
{
case MFMailComposeResultCancelled:
[[[UIAlertView alloc]initWithTitle:#"Message Cancelled" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil]show];
break;
case MFMailComposeResultSent:
[[[UIAlertView alloc]initWithTitle:#"Message Sent" message:#"Thank you for your help." delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil]show]; break;
default:
break;
}
[self dismissViewControllerAnimated:NO completion:nil];
}
On click of "OK" in the simulator, Xcode highlights a code in the main.m file, with the phrase "Thread 1: signal SIGABRT":
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
When I test the app on the iPhone, same thing, it crashes on click of OK.
Do you have any idea on how to solve this issue?
Many thanks in advance for your help and advice
The issue is most likely caused by the fact that you set the alert view's delegate to self and then you dismiss self. When you then tap OK on the alert view, it attempt to access its delegate but the delegate was dismissed so the app crashes.
There are two fixes:
Pass nil to the delegate parameter when creating the alert views. You have no need to process any alert view actions.
When dismissing the mail controller, do it by as follows:
code:
[controller dismissViewControllerAnimated:YES completion:nil];
If I am interpreting your question correctly, it is after you display the UIAlertView, and the user clicks on "OK" to dismiss your UIAlertView that you get the crash. If so, then the crash is most likely happening in your UIAlertView delegate inside:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
}
Try setting a breakpoint near the top of that method, then step through the code until the error occurs (after you press "OK").
In there you will probably find that you are attempting to access an object that no longer exists. If you cannot locate the error there, then it would be best to post the code for your didDismissWithButtonIndex: method.
I have created a password protected app. The app is allowed to run in background.
When it returns to foreground, I display an alert to prompt the user for password, by overriding the applicationWillEnterForeground: method in appdelegate like so-
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if (/*password is enabled*/) {
alertview = [[UIAlertView alloc] initWithTitle:#"LOGIN"
message:#"Enter app password"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
alertview.alertViewStyle = UIAlertViewStyleSecureTextInput;
pwdTF = [alertview textFieldAtIndex:0];
[pwdTF setDelegate:self];
[alertview show];
}
}
However, the alert takes a little time to appear. During this time, the view remains vulnerable.
Is there a way to make uialertview show instantly?
dispatch_async(dispatch_get_main_queue(), ^{
<# Write UI related code to be executed on main queue #>
});
Below is the action and alert view. Why Won't This Work When The User Taps The Button?
Alert/Action
-(IBAction)myButton
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"" message:#"Call (804) 378-7120?"
delegate:self cancelButtonTitle:#"NO" otherButtonTitles:#"YES",nil];
[alert show];
[alert release];
}
What To Do With User Input
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==1)
{
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"tel://(804) 378-7120"]];
}
else
{
//Do whatever you want
}
}
As far as I remember, the index of the 1st other button is 0. So you say
if(buttonIndex==0)
{...open you URL...}
else
{
NSLog(#\"cancel\");
}
Per Apple documentation for Phone Links, the format is:
tel:1-408-555-5555
Similar to an email link, there is no //, and notice the use of hyphens, not parenthesis or space.
use this method when the user hit the YES option.
**-(void)phoneCall
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:099123456"]];
}**
Change the number 099123456 to the number what you want to call.
Hope this result useful.
I've got a problem,
I added Flurry SDK in my iOS app and want to show a full screen add each time when the user click in the "Ok" button of an uiAlertView. The problem is that it doesn't work.
So, I tried try to do it without the AlertView and it works perfectly.
Someone knows why it doesn't work after clicking on an AlertView.
// The call of the alertview
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"TitlePopupNewGame", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(#"CancelPopupNewGame", nil) otherButtonTitles:NSLocalizedString(#"YesPopupNewGame", nil), nil];
myAlert.tag = 1;
myAlert.delegate = self;
[myAlert show];
// Alertview method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (alertView.tag == 1 && buttonIndex == 0){
[self showInterstitial];
}
}
// ShowInterstitial method
-(void) showInterstitial{
if ([FlurryAds adReadyForSpace: #"Full screen banner"]) {
[FlurryAds displayAdForSpace: #"Full screen banner"
onView:mv];
[FlurryAds fetchAdForSpace:#"Full screen banner"
frame:mv.frame size:FULLSCREEN];
} else {
// fetch an ad
[FlurryAds fetchAdForSpace:#"Full screen banner"
frame:mv.frame size:FULLSCREEN];
}
}
Thanks