I'm trying to deny a certain tabBarItem from pulling its action if there is no internet connection.
This is my code:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
ONLog(#"tab selected: %#", item.title);
if (item.tag == 2) {
if (![[InternetManager sharedManager] isInternetWorking]) {
[self setSelectedIndex:1];
UIAlertView *noInternet = [[UIAlertView alloc] initWithTitle:#"No Internet Connection" message:nil delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[noInternet show];
}
}
}
Issue is: The alert view is being called but the "setSelectedIndex" is not doing its work...
Any ideas?
Check what the value of self.selectedItem is when the method is first called. Maybe the selected item isn't actually set as selected until after this method is called, so [self setSelectedIndex:1] is being called but the item that the user tapped gets selected immediately after.
Related
So I have the following code and when the round is over it pops up with the following UIAlertView. Now when the user pushes the leaderboards button I want it to run the - (void) statement I have that displays the leaderboards. Please not that this is all inside of a sprite kit view controller. How should I do this?
Also I have my void statement in a different class, is there anyway to bring that over via an #import?
- (void) gameEnded
{
// indicate our game state as stopped
_gameState = STOPPED;
// create a message to let the user know their score
NSString *message = [NSString stringWithFormat:#"You scored %d this time", _score];
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
[av show];
// reset the score tracker for the next game
_score = 0;
//reset playing area
[self removeAllBlocks];
[self addBlocks];
}
Here:
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
You need to set the delegate to 'self', or another class that you want be handling the alert view events as its delegate. That class must conform to the UIAlertViewDelegate, for example:
#interface YourController : YourControllerSuperClass <UIAlertViewDelegate>
Then, Xcode will probably suggest you to implement:
– alertView:clickedButtonAtIndex:
As this is the method called by the alert view on its delegate when a button is pressed.
Here you'll receive a reference to your alert view and the index of the pressed button.
With this, you can find which action was performed.
For example:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
// In case there are more then one alert view and a reference to each of the alert views are kept.
if(alertView == self.avAlertView){
switch(buttonIndex){
// Your button's cases!
}
}
}
Your current Controller should implement UIAlertViewDelegate, and call the method alertView:clickedButtonAtIndex: with the index of your leaderboard button.
Your CustomController.h:
#import <UIKit/UIKit.h>
#interface AdsEventViewController : UITabBarController<UIAlertViewDelegate>
#end
Your CustomController.m:
[...]
- (void) gameEnded
{
// indicate our game state as stopped
_gameState = STOPPED;
// create a message to let the user know their score
NSString *message = [NSString stringWithFormat:#"You scored %d this time", _score];
// show the message to the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Game over!"
message:message
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Leaderboards",nil];
[av show];
// reset the score tracker for the next game
_score = 0;
//reset playing area
[self removeAllBlocks];
[self addBlocks];
}
[...]
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex == _LEADERBOARD_BUTTON_INDEX_ ){
// leaderboard method
}
}
I have an IF statement that checks labels to see if a label is empty, if it is show an alert.
if ([_DOBDate.text length] == 0)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Cannot Proceed"
message:#"Please Submit your DOB and Gender"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
later on in the function I have perform segue, like this :
[self performSegueWithIdentifier:#"SetUptoMain" sender:self];
True, the alert does fire when the label is blank, but it also performs the segue. This perform segue line is not in the IF statement. So I would have thought it would have ran the IF statement and stayed there till I pressed OK. OK would be staying on the same view controller.
The segue is performed, is this due to Blocks ? any advice ?
So if the USER pressed Ok from the UIAlert the VC does not move, it stays where it was so the user can enter the details required.
This is my code :
- (IBAction)SettingsSave:(id)sender {
if ([_DOBDate.text length] == 0)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Cannot Proceed"
message:#"Please Submit your DOB and Gender"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
more code...
then at the end
[self performSegueWithIdentifier:#"SetUptoMain" sender:self];
}
thanks
Seems to be an if/else logic issue. Read about it.
-(IBAction)yourAction:(id)sender
{
if ([_DOBDate.text length] == 0)
{
//Show your AlertView as you did
}
else
{
//put the rest of your code, including the performSegue
}
}
UIAlertView doesn't block execution. It runs asynchronously. Therefore the code path will go into your if statement, then continue past it.
If you only want the segue to be performed after the user presses the alert view button then you need to implement UIAlertViewDelegate.
In your header file add something like this:
#interface MyController : UIViewController <UIAlertViewDelegate>
When you create the alert view do it like this:
UIAlertView *message = [[UIAlertView alloc] initWithTitle: #"Cannot Proceed"
message: #"Please Submit your DOB and Gender"
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[message show];
And add this method to implement the UIAlertViewDelegate.
- (void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex {
// perform segue here. You can also check what button was pressed based on the button index.
}
I have a UIAlertView with UIAlertViewStyleSecureTextInput. When the user taps "Login" and the password is correct, it will push the next ViewController. If the password is incorrect, it displays another UIAlertView prompting a single "Dismiss" button. What I am trying to do is when the user taps the return key, the "Login" button will be triggered. As it sits now, when the return key is pressed the alert just dismisses, regardless if the password is correct or not. Maybe there is a more logical solution than what I have attempted? Sorry if the title is a little confusing, I don't know how else to explain it. Any help is greatly appreciated. Thanks.
I have declared the first alert in my .h file, and conformed to the UIAlertViewDelegate and UITextFieldDelegate:
#interface EndViewController : UIViewController <UIAlertViewDelegate, UITextFieldDelegate>
#property (retain, strong) UIAlertView *loginRequiredMsg;
Method for the "Login" alert:
- (IBAction)resultsBtnPressed:(UIButton *)sender {
self.loginRequiredMsg = [[UIAlertView alloc]initWithTitle:#"Login Required"
message:#"Please enter the admin password"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Login", nil];
self.loginRequiredMsg.alertViewStyle = UIAlertViewStyleSecureTextInput;
[self.loginRequiredMsg textFieldAtIndex:0].delegate = self;
[self.loginRequiredMsg show];
}
Method for dismissing the keyboard when return key is tapped (I think I need to somehow call the next alert here if the password is incorrect, as currently it just dismisses the alert):
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Dismiss keyboard when return key is pressed
[self.loginRequiredMsg dismissWithClickedButtonIndex:self.loginRequiredMsg.firstOtherButtonIndex animated:YES];
return YES;
}
And finally the method containing the outcome of the password entered:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Login"]) {
UITextField *password = [alertView textFieldAtIndex:0];
// Basic login authentication
if ([password.text isEqualToString:#"admin"]) {
// Allocate & initialise ViewController
ResultsViewController *Results = [[ResultsViewController alloc]initWithNibName:#"ResultsViewController" bundle:nil];
// Push next ViewController
[self.navigationController pushViewController:Results animated:YES];
NSLog(#"Show results");
} else {
UIAlertView *errorMsg = [[UIAlertView alloc]initWithTitle:#"Error"
message:#"Admin password is incorrect. Please try again."
delegate:self
cancelButtonTitle:#"Dismiss"
otherButtonTitles:nil];
[errorMsg show];
}
}
}
As discussed in the comments, you need to implement alertView:didDismissWithButtonIndex: which tells you when the alert view has been dismissed. When you tap the return key, it calls that method with the index of the OK button.
In my application i want alertview in many views.So what i did is just wrote a single alertview in a utility class and use it everywhere.This is working fine.
I even tried by setting <UIAlertViewDelegate> but in vain.
Utility Class
#interface SSUtility: NSObject<UIAlertViewDelegate> {
}
+(void)showAllert;
#end
#implementation SSUtility
+(void)showAllert{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"gotoappAppstore",#"") message:#"" delegate:self cancelButtonTitle:NSLocalizedString(#"Ok",#"") otherButtonTitles:nil];
[alert show];
[alert release];
}
#end
Now from my view
-(void)pressButton{
[SSutility showAllert]
}
Now i want to give a button action for alert view click and call a method on that button action.
So im stuck with,in which class i want to implement this method.I tried it in utility class and viewc controller but the method is not getting triggered when "ok" button is pressed.
-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
Can anyone please help me on this?
Thanks in advance.
You wire the alert view button response method by setting your alert view object delegate usually to the owner object and implementing the – alertView:clickedButtonAtIndex: method.
You need 4 parts in your code:
instantiate your UIAlertView object
send show message to your UIAlertView object
set delegate
implement the delegate method
Example:
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:#"myTitle" message:#"myMessage" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitle:#"Another button"];
[myAlertView setDelegate:self];
[myAlertView show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) //index 0 is cancel, I believe
{
// code for handling cancel tap in your alert view
}
else if (buttonIndex == 1)
{
// code for handling button with index 1
}
}
I would recommend you get more familiar with how delegates work. This'll come back again a lot.
You set delegate:nil in your UIAlertView's init.
You should set to delegate:self, like this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"gotoappAppstore",#"") message:#"" delegate:self cancelButtonTitle:NSLocalizedString(#"Ok",#"") otherButtonTitles:nil];
in order to use the delegate in the same class (a.k.a. self).
As a sidenote, if you use Automatic Reference Counting (ARC), you do not need [alert release] (your Xcode compiler should warn you about this)
I have a delegate, which recives a message to delete a item with that item as an argument.
I want to show a confirmation AlertView, and then, if the users press Yes, i want to delete it.
So, what I have is
The delegate method that gets called:
- (void) deleteRecording:aRecording(Recording*)aRecording {
NSLog(#"Cancel recording extended view");
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(#"Cancel recording",nil)
message: NSLocalizedString(#"Are you sure you want to cancel the recording?",nil)
delegate: self
cancelButtonTitle: NSLocalizedString(#"No",nil)
otherButtonTitles: NSLocalizedString(#"Yes",nil), nil];
[alert show];
[alert release];
}
And the method thats checks which button has been pressed:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
{
NSLog(#"Delete was cancelled by the user");
}
break;
case 1:
{
NSLog(#"Delete deleted by user");
}
}
}
So, my question is, how can i send the aRecording parameter from the first method to the second?
Thanks a lot
Store that variable in a member variable (easiest solution)
If you are only passing an int variable, you can set AlertView tag
property.
myAlertView.tag = YOUR_INT;
According to the documentation,
Note : The UIAlertView class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is
private
and must not be modified.
So please use the 3rd method only if you are not intending to submit
app to app store. Thanks user soemarko ridwan for the tip.
For passing complex objects, subclass UIAlertView, add an object
property
#interface CustomAlertView : UIAlertView
#property (nonatomic, retain) id object;
#end
#implementation CustomAlertView
#synthesize object;
- (void)dealloc {
[object release];
[super dealloc];
}
#end
When you create AlertView
CustomAlertView *alert = [[CustomAlertView alloc]
initWithTitle: NSLocalizedString(#"Cancel recording",nil)
message: NSLocalizedString(#"Are you sure you want to cancel the recording?",nil)
delegate: self
cancelButtonTitle: NSLocalizedString(#"No",nil)
otherButtonTitles: NSLocalizedString(#"Yes",nil), nil];
[alert setObject:YOUR_OBJECT];
[alert show];
[alert release];
In the delegate
- (void)alertView:(TDAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSLog(#"%#", [alertView object]);
}