Application crash due to UIAlertController in ios 8 - iphone

I am developing custom keyboard app and in this app want to show UIAlertController but it crash with following error.
Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'
I used following code...
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Info"
message:#"You are using UIAlertController"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
So how can i solve?

Related

Keyboard will appeared automatically in ios 8.3 while displaying alertview or alertcontroller

I have updated Xcode 6.3 and ios8.3 check my code. then it gives me weird result.
here is first screen of my demo app. here is one textfield. when I type somethin in textfield keyboard open.
after typing completed. I have clicked on show alert button. I have displayed alert and output will be following.
After click on cancel.
I have displayed another alert then weird result keyboard should not open but when click on cancel button. display another alert and keyboard will appear automatically.
here is next screen output
following is the code
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Check Alert textField" message:#"keyboard should not be open" delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self showCustomAlertWithTitle:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Now Check" message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alertView show]
}
In my case i tried hiding keyboard, before showing alert, so it will not save keyboard in memory to present it again after dismissing it self.
for that you just need to dismiss keyboard which will take default animation time to hide, only then you should present alert view then it will not save that keyboard.
you must put around .6 second gap in hiding keyboard and presenting alert
[YOUR_TEXT resignFirstResponder];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_alertVw = [[UIAlertView alloc] initWithTitle:#"" message:#"message." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[_alertVw show];
});
Yep, it's strange.
But since iOS 8, I suggest to use the UIAlertController instead of UIAlertView.
Replace your code with this one:
- (IBAction)MethodShowAlert:(id)sender
{
[tmptxtField resignFirstResponder];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:#"Check Alert textField"
message:#"keyboard should not be open"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self showCustomAlertWithTitle:#"Now Check"];
}];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
-(void)showCustomAlertWithTitle:(NSString *)title{
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:title
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:YES completion:nil];
}
The keyboard will not show after the click on the button.
This was a change in behaviour introduced in iOS 8.3. Try downloading the iOS 8.2 simulator and you will see the old behaviour.
The result of my analysis was the following:
When an alert is shown, it saves the currently showing keyboard.
When an alert has completed the dismiss animation, it restores the previously saved keyboard.
So in -[id<UIAlertViewDelegate> alertView:clickedButtonAtIndex:], you are between those states. So what happens with two Alerts that are shown at the same time:
Show Alert1. Save visible keyboard. Hide keyboard.
User taps on alert.
Show Alert2. Save that there is no keyboard.
Alert1 completes dismiss animation. Restore saved keyboard. Keyboard is visible.
User taps on alert.
Alert2 is dismissed. Restore that there is no keyboard. Hide keyboard.
My recommendation is to use a UIAlertViewDelegate method that is called after the dismiss animation completes and show the next alert then.
Replace your alert method from below method.
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:messege title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
I also tried hiding the keyboard directly before presenting the alert.
What worked for me was calling [myTextField endEditing:YES]; instead of [myTextField resignFirstReponder];
This let the keyboard stay hidden, even after the alert was dismissed again.
The code looks like this:
[myTextField endEditing:YES];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"myTitle"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"NO"
style:UIAlertActionStyleCancel
handler:nil];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"YES"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];

UIAlertView changes to landscape when App is locked in portrait only in iOS8

I have an app and its orientation is locked as portrait mode, but when I have a UIAlertView and turn the iPhone to landscape, the alert changes the orientation and crops the alert's overlay. Only in iOS8.
Anyone had this error?
Yes I did get this issue. I have developed my code in iOS7 but had to do compatible with iOS 8 also. So I came across This link. I got my solution as follows:
When you are working with iOS7 UIAlertView works fine but if you are working with iOS8 you have to use UIAlertController. Use this kind of code:
if(SYSTEM_VERSION_LESS_THAN(#"8.0"))
{
alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"Invalid Coupon." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
else
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Warning" message:#"Invalid Coupon." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"OK", #"OK action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
}];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
}
Hope this will help you.

Using UIAlertView in an NSObject

I'm having a terrible time getting a UIAlertView to work within my custom NSObject class. In the research I've done it appears it should be possible but here's what I've run into.
First, here's my code:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"clickedButtonAtIndex: %d", buttonIndex);
}
-(void)testAlertView {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"List Contains Items"
message:#"List contains items. Remove all items & delete?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alertView show];
}
If I set the delegate to self this code crashes as soon as I tap a button. If I set it to nil clickedButtonAtIndex is never called. I've tried with and without using the <UIAlertViewDelegate>.
I know someone will ask 'why are you doing this in NSObject instead of in your UIViewController?'. Primarily because I want to separate this code out so I can use it from multiple places in my app. But also because this is a small piece of a larger block of logic that makes sense to be on it's own.
Any ideas what I'm doing wrong?
Thanks,
Rich
I had the same problem using ARC. The root of the problem was the same. I solved it by putting my custom NSObject into a "strong" property to make sure the object exists as long as the calling object (an UIVIewCOntroller in my case) exists, so when the delegate of my alert view is called I still have my custom object around and the delegate method works fine.
Add the NSObject as strong property:
#import "Logout.h" // is NSObject
.
.
.
#property (nonatomic, strong) Logout *logout;
Then you will get the delegatemethods called in your NSObject.
Don´t forget to register the delegate for the UIAlertView:
#interface Logout () <UIAlertViewDelegate>
and in your method:
UIAlertView *a = [[UIAlertView alloc] initWithTitle:#"title"
message:#"message" delegate:self cancelButtonTitle:#"cancel"
otherButtonTitles:#"ok", nil];
[a show];
How To Present An Alert View Using UIAlertController When You Don't Have A View Controller. Detail description.
Yes, you can only use UIAlertController only in UIViewController classes. So how can we do it in NSObject classes. If you see the description link given above you will get to the answer. To summarise in a line for the above description: Create a new window above the the current window. This new window will be our viewController where we display alert. So using this viewController you can call the method [presentViewController: animated: completion:].
Answer:
dispatch_async(dispatch_get_main_queue(), ^{
UIWindow* window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
window.rootViewController = [UIViewController new];
window.windowLevel = UIWindowLevelAlert + 1;
NSString *msg=#“Your mssg";
UIAlertController* alertCtrl = [UIAlertController alertControllerWithTitle:#“Title" message:msg preferredStyle:UIAlertControllerStyleAlert];
[alertCtrl addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"Yes",#"Generic confirm") style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
// do your stuff
// very important to hide the window afterwards.
window.hidden = YES;
}]];
UIAlertAction *cancelAction= [UIAlertAction actionWithTitle:#"cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
window.hidden = YES;
}];
[alertCtrl addAction:cancelAction];
//http://stackoverflow.com/questions/25260290/makekeywindow-vs-makekeyandvisible
[window makeKeyAndVisible]; //The makeKeyAndVisible message makes a window key, and moves it to be in front of any other windows on its level
[window.rootViewController presentViewController:alertCtrl animated:YES completion:nil];
});

objective C unable to switch views after scanning a QR code using ZBar

I am developping an App using XCode 4.2 that detects a QR code.
I am trying to make a switch view after QR code detection but it is not working at all
here is the code am using :
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
break;
NSString *string=symbol.data;
NSString *string2=#"1234";
if ([string isEqualToString:string2]) {
//this is the part that is not working : it doesn t load the AboutView at all
AboutView *about = [[AboutView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:about animated:YES];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"This is not a recognized QR code!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated: YES];
}
thanks
The issue is that the reader is the presented view controller in zbar's example code
-(void)presentReaderInViewController:(UIViewController*)vc
and you are treating self as if it is presented
You should use reader to present your AboutView and only dismiss reader in the else block
if ([string isEqualToString:string2]) {
//this is the part that is not working : it doesn t load the AboutView at all
AboutView *about = [[AboutView alloc] initWithNibName:nil bundle:nil];
[reader presentModalViewController:about animated:YES];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"This is not a recognized QR code!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated: YES];
}
You might also want to wait to dismiss reader in the delegate method of your alert view (create a soft reference and dismiss that... myReader = reader; when you set up the alertview)
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
[myReader dismissModalViewControllerAnimated: YES];
}

Alert view in iphone

I am new to iPhone application development. I want to design an alert view with 2 buttons: OK and Cancel. When the user touches the OK button, then I will print a message that says hello. When they touch the Cancel button, I will print cancel.
Please help; how do I do this?
To show the alert:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Do you want to say hello?"
message:#"More info..."
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Say Hello",nil];
[alert show];
[alert release];
To respond to whatever button was tapped:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Cancel Tapped.");
}
else if (buttonIndex == 1) {
NSLog(#"OK Tapped. Hello World!");
}
}
For more information, see the UIAlertView Class Reference and the UIAlertView Delegate Protocol Reference.
since the chosen answer is deprecated, here is the new solution:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"This is an alert."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
As shown in iOs Developer guide.
Show the alert with the following snippet
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Make an informed choice"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[alert show];
The delegate is set to self so when the alert is dismissed our own class will get a call back. The delegate must implement the UIAlertViewDelegate protocol.
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger) buttonIndex{
if (buttonIndex == 1) {
// Do it!
} else {
// Cancel
}
}
For Objective C:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"My Alert"
message:#"This is an action sheet."
preferredStyle:UIAlertControllerStyleAlert]; // 1
UIAlertAction *firstAction = [UIAlertAction actionWithTitle:#"one"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button one");
}]; // 2
UIAlertAction *secondAction = [UIAlertAction actionWithTitle:#"two"
style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
NSLog(#"You pressed button two");
}]; // 3
[alert addAction:firstAction]; // 4
[alert addAction:secondAction]; // 5
[self presentViewController:alert animated:YES completion:nil]; // 6
For Swift:
let alert = UIAlertController(title: "My Alert", message: "This is an action sheet.", preferredStyle: .Alert) // 1
let firstAction = UIAlertAction(title: "one", style: .Default) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button one")
} // 2
let secondAction = UIAlertAction(title: "two", style: .Default) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button two")
} // 3
alert.addAction(firstAction) // 4
alert.addAction(secondAction) // 5
presentViewController(alert, animated: true, completion:nil) // 6
Here are a few ways of showing Alert messages on the iPhone
please check this link for more samples and screenshots .
(XCode project with source code included)
Simple Action Sheet
OK/Cancel Action Sheet
Simple Alert
// open a alert with an OK and cancel button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"UIAlertView"
message:#"My message" delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[alert show];
[alert release];
For debug output you could use (sometimes it happens that you can't use NSLog due to bugs that only appear when app is launched on the device and not from Xcode):
#define MY_ALERT(str) [[[UIAlertView alloc] initWithTitle:#"System Alert" message:str delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show]
Then, in your code you could do, for example:
MY_ALERT(NSStringFromCGRect(someView.frame))
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:#"Hello world" message:#"This is an alert view" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
In this way we create an object of class UIAlertView and set the title "Hello world" and the message "This is an alert view " and the title of button as ok.
For a detail answer visit this blog