I am new to Objective C but have been working on Swift for a while now. I assumed Objective c to be logically similar to swift. I have to present an alert controller while I am processing a json data request; so I had to use dispatch async to get it to work in swift. Here's the code I used in Swift:
func alertMessage(message : String) -> Void {
let alert = UIAlertController(title: "Alert", message: message, preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(okAction)
dispatch_async(dispatch_get_main_queue(),{
self.presentViewController(alert, animated: true, completion: nil)
})
}
But I tried to do the same thing in objective C like so
- (void)alertMessage : (NSString*) message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:NULL];
[alert addAction:okAction];
[dispatch_async(dispatch_get_main_queue(), ^(void){
[self presentViewController:alert animated:true completion:NULL];
})];
}
I'm getting an error "expected identifier". What am I doing wrong?
Its just syntax error. Try following
- (void)alertMessage : (NSString*) message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:NULL];
[alert addAction:okAction];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self presentViewController:alert animated:true completion:NULL];
});
}
Because “dispatch_async” is a C function, you should call it like this.
- (void)alertMessage : (NSString*) message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:NULL];
[alert addAction:okAction];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alert animated:true completion:nil];
});
}
Can try now
- (void)alertMessage : (NSString*) message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:NULL];
[alert addAction:okAction];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self presentViewController:alert animated:true completion:nil];
});
}
Output:
Happy coding..
Related
I have the following implementation to be reused entire app. I store the following code in the Utility.m class.
CustomViewController.m
How can I capture click event in the following
[self presentViewController:[Utility oneButtonDisplayAlert:#"Error" withMessage:#"Please try again later"] animated:YES completion:nil];
Utility.m
+ (UIAlertController *)oneButtonDisplayAlert : (NSString*)title withMessage : (NSString*) message
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle your yes please button action here
}];
[alert addAction:yesButton];
return alert;
}
Add a block parameter to your oneButtonDisplayAlert:withMessage: method. Call that block inside the alert action's handler.
+ (UIAlertController *)oneButtonDisplayAlert:(NSString *)title withMessage:(NSString *)message andOKHandler:(void (^)(void))handler
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (handler) {
handler();
}
}];
[alert addAction:yesButton];
return alert;
}
And then call it as:
UIAlertController *alert = [Utility oneButtonDisplayAlert:#"Error" withMessage:#"Please try again later" andOKHandler:^{
// whatever code you need when OK tapped
}];
[self presentViewController:alert animated:YES completion:nil];
Note: Code in this answer might have a typo. Syntax not verified.
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];
I have tried several ways to use UIAlertController,instead of UIAlertView. I tried several ways but I cannot make the alert action work.
Here is my code that works fine in IOS 8 and IOS 9 but is showing up with deprecated flags. I tried the elegant suggestion below but I can't make it function in this context. I need to submit my app and this is the last thing to address. Thank You for any further suggestions. I am a newbie.
#pragma mark - BUTTONS ================================
- (IBAction)showModesAction:(id)sender {
NSLog(#"iapMade: %d", iapMade3);
// IAP MADE ! ===========================================
if (!iapMade3) {
//start game here
gamePlaysCount++;
[[NSUserDefaults standardUserDefaults]setInteger:gamePlaysCount forKey:#"gamePlaysCount"];
NSLog(#"playsCount: %ld", (long)gamePlaysCount);
if (gamePlaysCount >= 4) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE
delegate:self
cancelButtonTitle:#"Yes, please"
otherButtonTitles:#"No, thanks", nil];
[alert show];
NSString *path = [[NSBundle mainBundle] pathForResource:#"cow" ofType:#"wav"];
_pop =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[_pop play];
[self dismissViewControllerAnimated:true completion:nil];
} else {
if (gamePlaysCount == 1) {
// Create & store the next 5 mins when player gets 3 more lives
nextDateToPlay = [[NSDate date] dateByAddingTimeInterval:60*60*0.1];
NSLog(#"CURRENT DATE: %#", [NSDate date]);
NSLog(#"NEXT DAY: %#", nextDateToPlay);
[[NSUserDefaults standardUserDefaults]setObject: nextDateToPlay forKey:#"nextDateToPlay"];
NSLog(#"nextDateToPlay: %#", nextDateToPlay);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE2
delegate:self
cancelButtonTitle:#"Got it!"
otherButtonTitles:#"Start", nil];
[alert show];
} else {
if (gamePlaysCount == 3) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE3
delegate:self
cancelButtonTitle:#"Yep, I Know!"
otherButtonTitles:#"Start", nil];
[alert show];
}
}
}
}
}
// IAP NOT MADE =============================
#pragma mark - ALERTVIEW DELEGATE ============================
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"Yes, please"]) {
UIStoryboard *storyboard = self.storyboard;
MenuViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"Store"];
svc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:svc animated:YES completion:nil];
}
}
From iOS8 Apple provide new UIAlertController class which you can use instead of UIAlertView which is now deprecated, it is also stated in deprecation message:
UIAlertView is deprecated. Use UIAlertController with a preferredStyle
of UIAlertControllerStyleAlert instead
So you should use something like this
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Yes, please"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle your yes please button action here
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"No, thanks"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
//Calling
[self showMessage:#"There is no internet connection for this device"
withTitle:#"Error"];
//Method
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
If you want to use this alert in NSObject class you should use like:
-(void)showMessage:(NSString*)message withTitle:(NSString *)title{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alertController animated:YES completion:^{
}];
});
}
Swift version of new implementation is :
let alert = UIAlertController(title: "Oops!", message:"your message", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay.", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
Xcode 8 + Swift
Assuming self is a UIViewController:
func displayAlert() {
let alert = UIAlertController(title: "Test",
message: "I am a modal alert",
preferredStyle: .alert)
let defaultButton = UIAlertAction(title: "OK",
style: .default) {(_) in
// your defaultButton action goes here
}
alert.addAction(defaultButton)
present(alert, animated: true) {
// completion goes here
}
}
Make UIAlertController+AlertController Category as:
UIAlertController+AlertController.h
typedef void (^UIAlertCompletionBlock) (UIAlertController *alertViewController, NSInteger buttonIndex);
#interface UIAlertController (AlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock;
#end
UIAlertController+AlertController.m
#implementation UIAlertController (NTAlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock {
UIAlertController *alertController = [self alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
if(cancelButtonTitle != nil) {
UIAlertAction *cancelButton = [UIAlertAction
actionWithTitle:cancelButtonTitle
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_CANCEL); // CANCEL BUTTON CALL BACK ACTION
}];
[alertController addAction:cancelButton];
}
if(otherButtonTitle != nil) {
UIAlertAction *otherButton = [UIAlertAction
actionWithTitle:otherButtonTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_OTHER); // OTHER BUTTON CALL BACK ACTION
}];
[alertController addAction:otherButton];
}
[controller presentViewController:alertController animated:YES completion:nil];
return alertController;
}
#end
in your ViewController.m
[UIAlertController showAlertIn:self WithTitle:#"" message:#"" cancelButtonTitle:#"Cancel" otherButtonTitles:#"Other" tapBlock:^(UIAlertController *alertController, NSInteger index){
if(index == ALERTACTION_CANCEL){
// CANCEL BUTTON ACTION
}else
if(index == ALERTACTION_OTHER){
// OTHER BUTTON ACTION
}
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
NOTE: If you want to add more than two buttons then add another
more UIAlertAction to the UIAlertController.
Use UIAlertController instead of UIAlertView
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
I tried the above methods, and no one can show the alert view, only when I put the presentViewController: method in a dispatch_async sentence:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:alert animated:YES completion:nil];
});
Refer to Alternative to UIAlertView for iOS 9?.
-(void)showAlert{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
[self showAlert]; // calling Method
Check this:
UIAlertController *alertctrl =[UIAlertController alertControllerWithTitle:#"choose Image" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *camera =[UIAlertAction actionWithTitle:#"camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self Action]; //call Action need to perform
}];
[alertctrl addAction:camera];
-(void)Action
{
}
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Are you sure you want to logout?"
message:#""
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Logout"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:noButton];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];
This question already has answers here:
UIAlertView/UIAlertController iOS 7 and iOS 8 compatibility
(14 answers)
Closed 7 years ago.
I am using AlertView since release of iOS8,but after release of iOS8 UIAlertView is replaces by UIAlertViewController. Then how to use it as a UIAlertView.
AlertView in Swift in ios8
var alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
UIAlertController * myAlert= [UIAlertController
alertControllerWithTitle:#"My Alert"
message:#"put a message here"
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:MyAlert animated:YES completion:nil];
if ([UIAlertController class])
{
// use UIAlertController
UIAlertController *alert= [UIAlertController
alertControllerWithTitle:#"Enter Folder Name"
message:#"Keep it short and sweet"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action){
//Do Some action here
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
NSLog(#"cancel btn");
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
use this code
I have created an alert as follows
UIAlertView *alert1 = [[UIAlertView alloc]
initWithTitle:#"Title"
message:#"message"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:nil];
[alert1 show];
But it does not display the title. How can I fix this?
I try in Xcode 5.1.1 in your code is working fine in my Xcode, see the output
and i also try in Xcode 6.0.1 your code is working fine in my Xcode, see the output
if u r using in Xcode 6.0.1 in swift
UIAlertView is deprecated. Use UIAlertController with a preferredStyle of
UIAlertControllerStyleAlert instead.
UIAlertController * alert1 = [UIAlertController alertControllerWithTitle:#"Title" message:#"Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* aaction = [UIAlertAction actionWithTitle:#"okay" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[alert1 dismissViewControllerAnimated:YES completion:nil];
}];
[alert1 addAction:aaction];
[self presentViewController:alert1 animated:YES completion:nil];
another choice
let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
presentViewController(alertController, animated: true, completion: nil)
need more help use this link http://www.appcoda.com/uialertcontroller-swift-closures-enum/
Try this for iOS 8
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"AlertView" message:#"I am an AlertView" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
I have just removed the following method from my ViewController category class and it's working fine!
- (void)setTitle:(NSString *)title
{
// My Code
}
From Xcode 6.0 UIAlertView class:
UIAlertView is deprecated. Use UIAlertController with a preferredStyle
of UIAlertControllerStyleAlert instead.
On swift ( iOS 8 and OS X 10.10 ), you can do this:
var alert = UIAlertController(title: "Alert Title", message: "Alert Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler:{ (ACTION :UIAlertAction!)in
println("User click Ok button")
}))
self.presentViewController(alert, animated: true, completion: nil)
func handleCancel(alertView: UIAlertAction!)
{
println("User click cancel button")
}
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];
Hope it is useful to you..