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];
}
Related
There is a game that i load in the WKWebView and this Alert and textField appear after the game is finished. I want to display keyboard when user taps on the textField. But the problem is there is no code to display this alert and textfield, otherwise i would have managed the textField to becomeFirstResponder().
Desperately need some help. I would really appreciate it.
Okay so i have found the solution. I had a textField in custom Alert/Popup in WkwebView and i wanted the textField to becomeFirstResponder() so i could take user input.
// So i Implemented WKUIDelegate..
#import <WebKit/WebKit.h>
#interface MyController : UIViewController<WKUIDelegate>
Assigned the Delegate..
- (void)viewDidLoad {
[super viewDidLoad];
_webkitView.UIDelegate = self;
}
//implemented delegate function.
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"BlockChaid Id, Email or Username"
message:prompt
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = prompt;
textField.secureTextEntry = NO;
textField.text = defaultText;
}];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(nil);
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(#"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler([alert.textFields.firstObject text]);
}]];
[self presentViewController:alert animated:YES completion:nil];
}
After successful build, this was the output.
I tapped the textField, and javaScript Alert appeared.
This right here is what i wanted to achieve.
Maybe i was not good enough to explain my question, but this is what i was asking for. Thank you :)
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];
In this code the alert action is shown every time the app become active:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Please make your choice"
message:#"Would you like a cup of coffee?"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *yesAction = [UIAlertAction actionWithTitle:#"YES"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
NSLog(#"You tapped YES");
}];
UIAlertAction *maybeAction = [UIAlertAction actionWithTitle:#"MAYBE"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
NSLog(#"You tapped MAYBE");
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:nil];
[alertController addAction:yesAction];
[alertController addAction:maybeAction];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
Also, everything works as expected if I move the code block of the UIAlertController in viewDidAppear method.
But if I move the UIAlertController in viewDidLoad :
- (void)viewDidLoad {
UIAlertController *alertController [...]
[...]
[self presentViewController:alertController animated:YES completion:nil];
}
it doesn't works. The alert is not shown.
In viewDidLoad it is not part of the view hierarchy at that time hence it is silently ignored, on viewWillAppear at this time the view hierarchy is already set up hence the reason it works.
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.
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];