UIAlertController buttons are not visible - ios

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

Related

UIAlertController Action isnt working?

I have added a UIAlterController to my view. IT triggers fine, looks fine, and has its action, however tapping the Cancel action does nothing, it doesnt run any code, even if i add a block it wont execute it, it just doesnt seem to recognise the tap at all.
The code looks fine to me, so is there some other cause?
- (void)connectionFailed:(NSString *)title {
NSString *message = nil;
if ([title isEqualToString:NSLocalizedString(#"Connection Refused", #"connection Refused")]) {
message = NSLocalizedString(#"You do not have permission to use this console", #"incorrect permissions message");
}
else {
message = NSLocalizedString(#"Connection Failed", #"connection failed error message");
}
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
});
Edit: it appears the issue is down to view leaks causing problems, not sure of the fix but here is the breakdown in debugging:
debugging image of view stack
Use this:
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:nil];
Change UIAlertActionStyleDefault to UIAlertActionStyleCancel
Try this:
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
//your code here ...
}];
- (void)connectionFailed:(NSString *)title {
NSString *message = nil;
if ([title isEqualToString:NSLocalizedString(#"Connection Refused", #"connection Refused")]) {
message = NSLocalizedString(#"You do not have permission to use this console", #"incorrect permissions message");
}
else {
message = NSLocalizedString(#"Connection Failed", #"connection failed error message");
}
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style: UIAlertActionStyleCancel
handler:nil];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
});
just edited your cancel button alert style....
Try this :
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
UIAlertActionStyleDefault
handler:nil];

actionSheet:didDismissWithButtonIndex: is deprecated in iOS 8.3. What is the new method I have to use now?

These are deprecated, but I don't find the solution to improve it :
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"Take Photo", nil) style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action)
{
[self actionSheet:nil didDismissWithButtonIndex:0];
}]];
And:
[[[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(#"Cancel", nil) destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(#"Take Photo", nil), NSLocalizedString(#"Photo Library", nil), nil] showInView:controller.view];
Finally:
- (void)actionSheet:(__unused UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
switch (buttonIndex)
{
case 0:
{
sourceType = UIImagePickerControllerSourceTypeCamera;
break;
}
case 1:
Many thanks.
You can use UIAlerController as UIActionSheet is deprecated after iOS 8.3.
Please have look at below code for your reference.
UIAlertController* alert = [UIAlertController
alertControllerWithTitle:nil // Must be "nil", otherwise a blank title area will appear above our two buttons
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* button0 = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action)
{
// UIAlertController will automatically dismiss the view
}];
UIAlertAction* button1 = [UIAlertAction
actionWithTitle:#"Camera"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
// The user tapped on "Camera"
}];
UIAlertAction* button2 = [UIAlertAction
actionWithTitle:#"Photo Library"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
// The user tapped on "Camera"
}];
[alert addAction:button0];
[alert addAction:button1];
[alert addAction:button2];
[self presentViewController:alert animated:YES completion:nil];
Hope t his will guide you to get into UIAlterController in replace of UIActionSheet.
Thanks.
From Apple's website, It is clearly said you should use UIAlertController

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