I have this code, I'm trying to get a language selector on an Alert View, but I think that the delegate is not working.
#interface JumboEntranceViewController () <FBSDKLoginButtonDelegate, WSLoginDelegate, UIAlertViewDelegate, UITextFieldDelegate>
...
...
...
...
- (void) showLanguageSelector {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Idioma" message:#"" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"English",#"Español",#"Deustch", nil];
alert.delegate = self;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) { //CANCEL
[[LanguagesManager sharedInstance] setLanguage:#"es"];
}
else if(buttonIndex == 1) {
[[LanguagesManager sharedInstance] setLanguage:#"en"];
}
else if(buttonIndex == 2) {
[[LanguagesManager sharedInstance] setLanguage:#"es"];
}
else if (buttonIndex == 3) {
[[LanguagesManager sharedInstance] setLanguage:#"de"];
}
}
But I cannot not get into the function didDismissWithButtonIndex
Use this code. (UIAlertView is deprecated since iOS 9.0.)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Idioma" message:#"" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"English" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[LanguagesManager sharedInstance] setLanguage:#"en"];
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Español" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[LanguagesManager sharedInstance] setLanguage:#"es"];
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Deustch" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[LanguagesManager sharedInstance] setLanguage:#"de"];
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[[LanguagesManager sharedInstance] setLanguage:#"es"];
}]];
[[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:alert animated:YES completion:nil];
First of all, as mentioned in comments UIAlertView is deprecated since iOS 9.0. You should use UIAlertController instead, just like Xcode tells you with warnings both in the implementation of UIAlertView and of the delegate method
Anyway, I implemented an exact copy of your code and it works: are you sure the issue isn't in the LanguageManager singleton instead? Did you try putting a breakpoint in the first line of alertview:didDismissWithButtonIndex: to see if it gets called?
[edit] To clarify, following is the code, and here's the proof it works:
#import "ViewController.h"
#interface ViewController ()<UIAlertViewDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Idioma"
message:#""
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"English",#"Español",#"Deustch", nil];
alert.delegate = self;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) { //CANCEL
NSLog(#"0");
}
else if(buttonIndex == 1) {
NSLog(#"1");
}
else if(buttonIndex == 2) {
NSLog(#"2");
}
else if (buttonIndex == 3) {
NSLog(#"3");
}
}
#end
I am trying to fix on iOS 7+ an alert allowing me to input a 4 digit code, at the moment, the prompt appears, but the input field is blank and does not allow me to put anything in.
The methods below are used to call the pin code option, starting with the segmentedAction as seen below;
-(void)segmentedAction:(id)sender{
UISegmentedControl *control = (UISegmentedControl *)sender;
NSString *pincode = [self.objSettingAdapter getPinCode];
NSString *patternCode = [self.objSettingAdapter getPatternCode];
NSInteger pincodetype = control.selectedSegmentIndex;
if ((![pincode length]>0) && pincodetype==0) {
[self takePinInputFromUser:#"Choose Your PIN Code"];
}else if((![patternCode length]>0) && pincodetype==1) {
[self takePatterInputFromUser:#"Draw Pattern"];
}else {
[self.objSettingAdapter setPinCodeType:control.selectedSegmentIndex];
}
}
-(void)buttonAction:(id)sender{
UIButton *btn = (UIButton *)sender;
NSString *pincode = [self.objSettingAdapter getPinCode];
NSString *patternCode = [self.objSettingAdapter getPatternCode];
if ([btn.titleLabel.text isEqualToString:#"Reset PIN"] && (![pincode length]>0)) {
[self takePinInputFromUser:#"Choose Your PIN Code"];
}else if ([btn.titleLabel.text isEqualToString:#"Reset Pattern"] && (![patternCode length]>0)) {
[self takePatterInputFromUser:#"Draw Pattern"];
}else {
[self.objSettingAdapter setPinCodeType:([btn.titleLabel.text isEqualToString:#"Reset PIN"] ? 0 : 1)];
}
}
-(void)takePinInputFromUser:(NSString *)title{
AlertPinCode *prompt = [AlertPinCode alloc];
prompt = [prompt initWithTitle:title message:#"\n\n" delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Done"];
[prompt show];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
AlertPinCode *alertPin = (AlertPinCode *) alertView;
if (buttonIndex != [alertView cancelButtonIndex])
{
NSString *userPin = [alertPin enteredText];
if ([userPin length]<4) {
[alertPin dismissWithClickedButtonIndex:0 animated:YES];
[self takePinInputFromUser:#"Chose 4 Digit PIN Code"];
}else {
[self.objSettingAdapter setPinCodeType:0];
[self.objSettingAdapter setPinCode:userPin];
}
}
}
Try the following.
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Title" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
__weak typeof(UIAlertController) *weakAlertController = alertController;
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
__strong typeof(UIAlertController) *strongAlertController = weakAlertController;
UITextField *digitTextField = [strongAlertController.textFields firstObject];
NSString *pinCode = digitTextField.text;
NSLog(#"pin code: %#", pinCode);
// Do something with the PIN code
}];
[alertController addAction:cancelAction];
[alertController addAction:okAction];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = #"Input 4 Digit PIN Code";
}];
[self presentViewController:alertController animated:YES completion:nil];
you can use UIAlertViewController
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];
I have a login screen Where there are two text fields for username and password. When email is incorrect then i moved down the keyboard and show the appropriate alert for the user. When i clicked on cancel button of alertview then alert view disappears and scroll view goes upwards. This issue only comes on devices after iOS 8.1. On iOS 8.1 and earlier, it works fine. I don't understand what is the exact cause? Below is the code
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
if (txtActiveField == txtUsername) {
[txtPassword becomeFirstResponder];
}
else if (txtActiveField == txtPassword) {
[txtPassword resignFirstResponder];
//[self loginViaEmail:self];
[self performSelector:#selector(loginViaEmail:) withObject:btnLogin afterDelay:0.0];
}
return YES;}
-(IBAction)loginViaEmail:(id)sender{
//[txtActiveField resignFirstResponder];
if ([[txtUsername.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" "]] length] == 0)
{
[AppDelegate showWithTitle:title message:#"Please enter Username/Email for your account"];
}
else if ([txtPassword.text length] < 6)
{
if([[txtPassword.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" "]] length] == 0)
[AppDelegate showWithTitle:title message:#"Please enter Password"];
else
[AppDelegate showWithTitle:title message:#"Password contain minimum 6 characters"];
}
#pragma mark Show alert with message
+(void)showWithTitle:(NSString *)title message:(NSString *)msg
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
I think it is the issue with Alert view. As from iOS 8, AlertViewController comes instead of alert view. Try using below code which works fine on iOS 8.4 and below version
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
-(void)setupAlertCtr:(NSString*)choseMenuType
{
self.alertContForNew = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"İptal" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action)
{
}];
[self.alertContForNew addAction:cancel];
}
This code work on iOS 8 but when i try to use on iOS 7 get crash whats the problem ideas ?
Because UIAlertController is only support for iOS 8 and later, in iOS 7 we still have to use UIActionSheet or UIAlertView
so you have to put condition like below
if (ios8)// change your condition which check ios8 or later.
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Title" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* alertAction1 = [UIAlertAction actionWithTitle:#"Your title" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
//do what you want
}];
[alert addAction:cancelAction];
[alert addAction:alertAction1];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:#"Title" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Your Title",nil];
[actionSheet showInView:self.view];
}
and for iOS 7 you have to implement <UIActionSheetDelegate> and its method
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0:
//do what you want.
break;
case 1:
break;
default:
break;
}
}