UIAlertController Presenting in Weird Location - ios

Whenever I try to present this alert, it keeps appearing in some weird location.. Any ideas on how to fix this?
Screenshot
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Logout"
message:#"Are you sure you want to logout?"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"Yes"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
[[NSUserDefaults standardUserDefaults] setBool:#"NO" forKey:#"auth"];
[(AppDelegate *)[UIApplication sharedApplication].delegate changeRootViewController:[Login sharedLogin]];
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"No"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}]];
[self presentViewController:alert animated:YES completion:nil];

I think you changed window frame to double width and height so it showed there. You can log this to check.

Related

UIAlertController buttons are not visible

I have an Objective C project and want to show some alert to user, On some iPads the UIAlertController buttons are not visible, i have attached an image below.
Any one faced an issue like this? any workarounds?
Device Details
iOS 14.4
iPad Air 2
sample code used
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#“Alert” message:#“Message” preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:#“YES” style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
}];
UIAlertAction *noAction = [UIAlertAction actionWithTitle:#“NO” style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
}];
[alert addAction:yesAction];
[alert addAction:noAction];
[alert show];
image
this looks weird enough.
But I think the problem is that you are calling the show method.
And you need 'presentViewController' because it is no longer UIAlertView' but UIAlertViewController.
Please use my snippet.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//button click event
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancel];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
For a more in-depth study, I recommend this article

UIAlertController how add the tag value in obj c

Using this for UIAlertView
- (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
}
But now UIAlertView get deprecated. change my code
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
Here how can pass this tag value
alertView.tag = tag;
Help how to pass the tag value in UIAlertController. Thanks advance.
UIAlertController is the UIViewController , so we need to assign the tag for view, soe use alertController.view.tag.
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"sds" message:#"sdf" preferredStyle:UIAlertControllerStyleAlert];
alertController.view.tag = tag;
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
update
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"sds" message:#"sdf" preferredStyle:UIAlertControllerStyleAlert];
alertController.view.tag = 3;
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action)
{
// OK button tappped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
create a property of UIAlertController *alertController;, then use this alertController where ever you want. set the tag like this
alertController.view.tag = <YOUR TAG VALUE>;
to get the tag of that alertController, when you click on YES on alertController
//OK button tapped.
[self dismissViewControllerAnimated:YES completion:^{
NSInteger *tag = alertController.view.tag;
}];
Have not any tag property in UIAlertController. You can use block for getting button action.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert"
message:[NSString stringWithFormat:#"Your message"]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//NSLog(#"OK");
}]];
[self presentViewController:alert animated:YES completion:nil];
But you can use tag in this way-
alert.view.tag = 1;

how to prevent later code getting executed first in UIAlertController

i am working in shouldPrepareForSegue method but i am stuck in a problem
__block BOOL Stat;
if([identifier isEqualToString:#"SignOut"]){
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Are You Sure?" message:#"" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *can = [UIAlertAction actionWithTitle:#"CANCEL" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
Stat = NO;
[alert dismissViewControllerAnimated:YES completion:^{}];
}];
UIAlertAction *sign = [UIAlertAction actionWithTitle:#"SIGN OUT" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
Stat = YES;
NSLog(#"%d",Stat);
}];
[alert addAction:can];
[alert addAction:sign];
[self presentViewController:alert animated:YES completion:^{}];
NSLog(#"%d",Stat);
return Stat;
}else{
return YES;
}
value of Stat always returns 0 as it is getting executed before i respond to UIAlertController as the later code are getting executed first how to prevent it.
you can create a function with completion block like below and call this where you need and just check flag
- (void)signOutWithcompletionHandler:(void (^)(BOOL flag))completionHandler
if([identifier isEqualToString:#"SignOut"]){
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Are You Sure?" message:#"" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *can = [UIAlertAction actionWithTitle:#"CANCEL" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
completionHandler(NO);
[alert dismissViewControllerAnimated:YES completion:^{}];
}];
UIAlertAction *sign = [UIAlertAction actionWithTitle:#"SIGN OUT" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
completionHandler(YES);
NSLog(#"%d",Stat);
}];
[alert addAction:can];
[alert addAction:sign];
[self presentViewController:alert animated:YES completion:^{}];
}else{
completionHandler(YES);
}
If you're running code that is essentially asynchronous, returning a value from the calling method is not going to work well (unless you set up some fairly complicated blocking).
Your best bet is to have the caller provide a delegate or listen for a notification instead of depending on the returned value. That way, you can trigger whatever you need to have happen in your completion handlers.

Alternative to UIAlertView for iOS 9?

UAlertView is deprecated in iOS 9 and later. What would be an alternative?
UIAlertView *new = [[UIAlertView alloc] initWithTitle:#"Success" message:#"Your InApp Purchases were successfully restored" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[new show];
You can use this code to replace an alert view:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Title" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alertController animated:YES completion:nil];
If you need multiple actions you can use:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Title" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:#"Button 1" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// action 1
}]];
[alertController addAction:[UIAlertAction actionWithTitle:#"Button 2" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// action 2
}]];
[alertController addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self dismissViewControllerAnimated:YES completion:nil];
}]];
[self presentViewController:alertController animated:YES completion:nil];
You get often detailed information including the replacement suggestion by ⌘-clicking on the symbol which displays the class/method declaration.
In case of UIAlertView you will see
"UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead"
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];
I made a category for that:
+ (void)alertViewWithTitle:(NSString *)aTitle message:(NSString *)aMessage viewController:(UIViewController *) aVC
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:aTitle ? aTitle : #""
message:aMessage
preferredStyle:UIAlertControllerStyleAlert];
UIViewController *topVC = aVC ? aVC : [UIApplication sharedApplication].keyWindow.rootViewController;
[topVC presentViewController:alert animated:YES completion:nil];
}
The parameters aTitle and aVC are optional but aVC should be used if known.
PS: avoid the "new" as a variable name this is a reserved word, I actually don't know if it will compile though.
UIAlertController has been around since iOS 8.
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Enter User Credentials"
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
I have use "UIAlertController" on iOS 8 and later. Let see:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Success" message:#"Your InApp Purchases were successfully restored" preferredStyle:UIAlertControllerStyleAlert];
And add buttons:
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
Remember:
[alertController addAction:okAction];
Then show it:
[self presentViewController:alertController animated:YES completion:nill];
If you want to show a actionsheep, you change
"preferredStyle:UIAlertControllerStyleActionSheet"

Popup without tile in iOS

I want to show popup if I click a button on toolbar. I am using ios 8 SDK.
I am using below code to do the same, but now I want to remove title from it.
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[appDelegate encTitle]
delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil
otherButtonTitles:#"Add Bookmark", #"Cancel",nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
actionSheet.cancelButtonIndex = 1; // make the second button red (destructive)
[actionSheet showInView:self.view]; // show from our table view (pops up in the middle of the table)
[actionSheet release];
If I use like this initWithTitle:#"" then also title block comes in the popup.
currently it is like below image
want to achieve like this
Please help me to fix the issue.
After using UIalertviewController as suggested by sweetAngel, its coming like this in iPhone 4s....please help to show it properly in all the devices.
If you are using iOS 8, then you can try this one :
UIAlertController *alert1 = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"Add Bookmark" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
// Your code for bookmark
[alert1 dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[alert1 dismissViewControllerAnimated:YES completion:nil];
}];
[alert1 addAction:ok];
[alert1 addAction:cancel];
[self presentViewController:alert1 animated:YES completion:nil];
In iOS 8, not only you should definetely not use retain / release, but in order to present an action sheet you should use UIAlertController because UIActionSheet is deprecated. Here's an example:
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:#"Evacuate Building!" message:#"" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *destructiveAction = [UIAlertAction actionWithTitle:#"Kick through door" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
// destructive action completion
}];
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:#"Walk calmly" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// default action completion
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Do nothing" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
// cancel action completion
}];
[actionSheet addAction:destructiveAction];
[actionSheet addAction:defaultAction];
[actionSheet addAction:cancelAction];
[self presentViewController:actionSheet animated:YES completion:nil];

Resources