UIAlertView and UIActionSheet not displaying properly in iOS 8 - objective-c

UIAlertView and UIActionSheet not displaying properly in iOS 8, its hiding the view controller, also In alert view title is not displaying. I am running the app from Xcode 5.1.1.

Did you added any category for ViewController in your application. like below shown
#implementation UIViewController (CustomeAction)
- (void)setTitle:(NSString *)title{
// YOU CODE///
}
#end
This may the issue. I have solved by removing this category - (void)setTitle:(NSString *)title.
Note: From iOS 8, UIAlertViewController is inherited from UIViewController. If you use category method, it will be effect on UIAlertView & UIActionSheet titles.
You can refer apple docs at UIAlertController Class Reference

It should be noted, that UIAlertView and UIActionSheet is deprecated in iOS 8. You can check out this question or the apple link. May be it will help you.

You can use following code using UIAlerController for XCode 6 and IOS 8
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Title"
message:#"Your Message"
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];
For ActionSheet
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Title"
message:#"Your Message"
preferredStyle:UIAlertControllerStyleActionSheet];

Related

in iOS 13 [UIApplication sharedApplication] delegate].window does not work using objective-c

I need to display alert from a class which is non-UIView using objective-c.
Below is the code:
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:#“Sample” message message:#“hello message” preferredStyle:UIAlertControllerStyleAlert];
[alertVC addAction:[UIAlertAction actionWithTitle:#"Okay" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {}]];
[[[UIApplication sharedApplication] delegate].window.rootViewController presentViewController:alertVC animated:YES completion:nil];
this above does not work anymore and I could not any other alternative for same code in objective-c.
I came across this link How to resolve: 'keyWindow' was deprecated in iOS 13.0 but solution is in Swift,not in objective-c .
Thanks
The problem is that in iOS 13, this expression...
[[UIApplication sharedApplication] delegate].window.rootViewController
...is nil. That's because the window property belongs to the scene delegate, not the app delegate. You would do better to access the window by way of the UIApplication itself. For example, look through the application's windows and find the one that is key.
You are trying to present the viewcontroller in key window which will create exception. Try this code
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Tap!" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];
I think in your case most simple would be to use the following as replacement of your last code row
[UIApplication.sharedApplication.windows.lastObject.rootViewController
presentViewController:alertVC animated:YES completion:nil];

UIAlertController disappearing since iOS 13

I have the following function that pops up a UIAlert which allows the user to update their Haptic Feedback setting:
- (void)requestHapticSetting{
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
if(isHapticOn){
hapticMessage = #"Haptic feedback is currently\nturned ON.\nPlease update preference.";
}
else {
hapticMessage = #"Haptic feedback is currently\nturned OFF.\nPlease update preference.";
}
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Haptic Setting"
message:hapticMessage
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* onAction = [UIAlertAction actionWithTitle:#"TURN ON" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOn];
}];
UIAlertAction* offAction = [UIAlertAction actionWithTitle:#"TURN OFF" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOff];
}];
[alert addAction:offAction];
[alert addAction:onAction];
[alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
I have used this for a couple of years and it works great.
However, since updating to iOS 13 and updating to the latest Xcode, my alert pops up for less than a second before closing.
What has changed that could be making this happen? Thanks in advance.
What seems to have changed is that on iOS 12 and previous versions your app would hold a strong reference to the window just by calling [alertWindow makeKeyAndVisible];, in iOS 13 it doesn't anymore.
What's happening is that the only strong reference to your alertWindow is in your requestHapticSetting func, and as soon as this func returns, the window is destroyed, thus removing your alert from the view.
This might be fixed just by adopting iOS 13 scenes, but I haven't tested that. What I can suggest, which won't properly work if you are using scenes, is holding your alert window in a strong variable somewhere in your code, and then using it to present the alert. I'd suggest doing so in a singleton or AppDelegate itself.
//AppDelegate.h
...
#property (strong) UIWindow *alertWindow;
....
//AppDelegate.m
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
self.alertWindow = [[UIWindow alloc] init];
self.alertWindow.rootViewController = [[UIViewController alloc] init];
self.alertWindow.windowLevel = UIWindowLevelAlert + 1;
...
}
...
//Your class that's presenting the alert
#import "AppDelegate.h"
...
- (void)requestHapticSetting{
AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication;
[appDelegate.alertWindow makeKeyAndVisible];
if(isHapticOn){
hapticMessage = #"Haptic feedback is currently\nturned ON.\nPlease update preference.";
} else {
hapticMessage = #"Haptic feedback is currently\nturned OFF.\nPlease update preference.";
}
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Haptic Setting"
message:hapticMessage
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* onAction = [UIAlertAction actionWithTitle:#"TURN ON" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOn];
[appDelegate.alertWindow setHidden:YES];
}];
UIAlertAction* offAction = [UIAlertAction actionWithTitle:#"TURN OFF" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self saveHapticSettingOff];
[appDelegate.alertWindow setHidden:YES];
}];
[alert addAction:offAction];
[alert addAction:onAction];
[appDelegate.alertWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
For Swift code, check this answer.
I have created a helper class which support new UIWindowScene and iOS 13.X and swift 5.X. You guys can try
https://github.com/emraz/ERAlertController

UIAlertController automatically dismisses in iOS 10

I have a UIAlertController in my AppDelegate and present it with my rootViewController when I receive a notification. But when the alert view pops up, it quickly dismisses itself instead of waiting for a tap event on the "Ok" button... Here's my code in AppDelegate.m. Any idea? Thanks!
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[self showNotification:"Success message here"];
}
- (void)showNotification:(NSString *)text {
UIAlertController* avc = [UIAlertController alertControllerWithTitle:#"Success" message:text
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleCancel handler:nil];
[avc addAction:ok];
[self.window.rootViewController presentViewController:avc animated:true completion:nil];
}
EDIT: I have another view controller; call it X. X's viewDidLoad function has a timer counting down before X dismisses itself and presents another view controller. I noticed an interesting timing issue here: when the notification comes slowly enough so that the UIAlertController appears after X's timer is up and another view controller has been presented, the alertController doesn't dismiss itself. If the opposite happens - the notification comes quickly enough making the UIAlertController appears before X dismisses itself, then the whole AlertController will be flushed when the timer is up (which makes sense, I guess...). How can I prevent this from happening?
You can use perform selector method, like this:
- (void)showNotification:(NSString *)text {
UIAlertController* avc = [UIAlertController alertControllerWithTitle:#"Success" message:text
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleCancel handler:nil];
[avc addAction:ok];
[self performSelector:#selector(dissmissAlert:) withObject:avc afterDelay:3.0];
[self.window.rootViewController presentViewController:avc animated:true completion:nil];
}
-(void)dissmissAlert:(UIAlertController *) alert{
[alert dismissViewControllerAnimated:true completion:nil];
}

UIAlertController not working Xibs?

In my project i am using xib's in that i want to show UIAlertController and perform some actions.but i am getting error.
Here is my code.
What is the mistake in my code.
when add xibView in UIVieController assign self in ParentViewController.
i.e
_xibView *objxibView = [[xibView alloc]init];
objxibView.parentViewController = self;
in Xib's xibView.h file create 1 property
#property (weak, nonatomic) UIViewController *parentViewController;
and in xibView.m File use below code
for UIAlertController in xib
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionOK = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:actionOK];
[self.parentViewController presentViewController:alert
animated:YES
completion:nil];
}

UIAlertController showing with delay

I'm experiencing a problem with UIAlertController on my app now migrated to iOS8 with Date Picker inside.
Below is the code.
UIAlertController *AlertView = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *ok = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action)
{
[AlertView dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction *set = [UIAlertAction actionWithTitle:NSLocalizedString(#"Set to today", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action)
{
[self set_to_today:nil];
[AlertView dismissViewControllerAnimated:YES completion:nil];
[self.tableView reloadData];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action)
{
[AlertView dismissViewControllerAnimated:YES completion:nil];
}];
UIDatePicker *datePicker = [[[UIDatePicker alloc] init] autorelease];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker setDate:data_appo];
[datePicker addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[AlertView.view addSubview:datePicker];
[AlertView addAction:ok];
[AlertView addAction:set];
[AlertView addAction:cancel];
[self.view bringSubviewToFront:datePicker];
[self presentViewController:AlertView animated:YES completion:nil];
UIAlertController and Date Picker is shown when the user select a row from UITableViewController.
The problem is the following:
first time the users select the row everything works fine...but if the user select "Cancel" and then select de tate again the UIAlertController takes 2-3 seconds to show up...this happens also in the simulator...
I'm getting crazy....this makes my app have a bad user experience.
Any help will be strongly appreciated
Thanks
Alex
I was having the same issue with a UIAlertController presented by selecting a row from a UITableView. The first time everything worked fine, and then when the user triggered the alert again there was a few seconds delay before the alert was actually presented.
As a workaround I used GCD:
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:AlertView animated:YES completion:nil];
});
It is probably a bug since -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath is already executed on the main thread.
I submitted a bug report to Apple: rdar://19285091
DispatchQueue.main.async {
self.present(alertView, animated: true, completion:nil)
}
Swift 3.0 version. Alternatively, setting animated: false also solved my problem.