how can I hide an empty tableview - ios

I have a problem and I hope someone here can help me out! Thanks in advance.
I have a "Scope"button(see screen shot!) which is linked to a segue and the segue goes to a tableview.
What I want to do is in the tableview controller that I decide if I should display something in the table or I should throw out an alertview.
What I did was:
if ([_countryScopes count] == 0) {
[self.view removeFromSuperview];
//no scope for this country
NSMutableString *message = [[NSMutableString alloc]initWithString:#"No scope information."];
UIAlertView *av = [[UIAlertView alloc] initWithTitle:countryName message:message delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
//av.tag = MAIN_ALERT;
[av show];
}
But somehow the empty table is still showing up.
Do you know, how I can get rid of this?
Thanks a lot!
Regards, Yashu

just show alert view after 0.1 seconds, i hope this will do the trick:
[av performSelector:#selector(show) withObject:nil afterDelay:0.1];

Related

Is there a way to stagger when multiple Alert Views show up in the same View Controller?

So I have two different UIAlertViews in the same view controller and both alerts can be triggered at the same time. When both alerts are triggered, both alerts pop up at the same time, with the alerts being layered on top of each other. Is there a way to stagger the alerts so that when the first alert comes up, the second alert will not pop up until the user dismisses the first alert? For my code, this is the format I'm using
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"ERROR!"
message:#"Error message here!"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
try the following:
create two properties
#property (weak, nonatomic) UIAlertView *visibleAlertView;
#property (strong, nonatomic) UIAlertView *pendingAlertView;
every time when you want to present an alertview from your code make a check
UIAlertView *newAlertView = [[UIAlertView alloc] init...
if (self.visibleAlertView) {
self.pendingAlertView = newAlertView;
} else {
self.visibleAlertView = newAlertView;
[newAlertView show];
}
and finally:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (self.pendingAlertView) {
UIAlertView *newAlertView = self.pendingAlertView;
self.pendingAlertView = nil;
self.visibleAlertView = newAlertView;
[newAlertView show];
}
}
hope that helps :)
EDIT
you could even stack the pending alertviews:
#property (strong, nonatomic) NSMutableArray *pendingAlertViews;
...
self.pendingAlertViews = [NSMutableArray array];
before presenting an alertview:
UIAlertView *newAlertView = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
if (self.visibleAlertView) {
[self.pendingAlertViews addObject:newAlertView];
} else {
self.visibleAlertView = newAlertView;
[newAlertView show];
}
and in dismiss:
if (self.pendingAlertViews.count > 0) {
UIAlertView *av = self.pendingAlertViews.firstObject;
[self.pendingAlertViews removeObjectAtIndex:0];
self.visibleAlertView = av;
[av show];
}
hope it helps :)
Why don't you make a class level variable that indicates an alertView is open. Then before you open one you check that variable and if it's set you don't pop up the second one. Instead you could have it set another variable that indicates the second box should pop up. Then in the - alertView:clickedButtonAtIndex: method you can pop up the second one if the second variable is set.
I think I am pretty late for this but still posting as It might be useful for someone looking for this.
I have created a AQAlertAction subclass for UIAlertAction. You can use it for staggering Alerts, the usage is same as you are using UIAlertAction. All you need to do is import AQMutiAlertFramework in your project or you can include class also (Please refer Sample project for that). Internally It uses binary semaphore for staggering the Alerts until user handle action associated with current alert displayed. Let me know if it works for you.

UIAlert and push segues

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.
}

UIAlertView Shows two times

Hope you are all doing good.
Where is my problem is concern one UIAlertView shows twice while executing the code. I have written it within -(void)viewDidAppear:(BOOL)animated as shown following
-(void)viewDidAppear:(BOOL)animated
{
//Finding city Name from coordinate
UIAlertView * alertForCoordinate=[[UIAlertView alloc]initWithTitle:#"Coordinate" message:[NSString stringWithFormat:#"latitude==>%f\nlongitude==>%f",self.userLocation.coordinate.latitude,self.userLocation.coordinate.longitude] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alertForCoordinate show];
[SVGeocoder reverseGeocode:CLLocationCoordinate2DMake(self.userLocation.coordinate.latitude, self.userLocation.coordinate.longitude)
completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (placemarks.count>0)
{
CLPlacemark * placemark=[placemarks objectAtIndex:0];
currentLocationUpcoming =[placemark locality];
UIAlertView * alert=[[UIAlertView alloc]initWithTitle:#"Location" message:[NSString stringWithFormat:#"currentLocation==>%#",currentLocationUpcoming] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[self.eventsTableView reloadData];
}
}];
}
As view appears First UIAlertView gets call and dismiss automatically then second gets call When I tap OK button of second alert and again first UIAlertView appears . I am struggling with it since last 4 hours and some of the answer put here also not intended the context in which I am working. Can anybody suggest me where I am wrong.
Thanks
You don't actually have the first UIAlertView showing twice - the animation just makes it look like this because you are showing two UIAlertViews in a row. You're probably seeing Alert 1-> Alert 2-> tap OK on Alert 2 -> Alert 1. This is because the UIAlertViews stack up if multiple are shown.
Think of it this way: Alert 1 shows first but animates for only a very brief period until it is interrupted by Alert 2 showing. Dismissing Alert 2 animates Alert 1 onscreen again, and even though it is still the same alert, it looks like it is showing twice.
Try this simple test case:
-(void)viewDidAppear:(BOOL)animated
{
[[[UIAlertView alloc] initWithTitle:#"Alert #1" message: delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
[[[UIAlertView alloc] initWithTitle:#"Alert #2" message: delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
}
You will see "Alert #1" for a fraction of a second, then "Alert #2" will remain onscreen. Tapping OK on "Alert #2" will show "Alert #1" again because it was below Alert #2 on the stack.
Your second alert overlaping the first one, and after dismissing second alert, the first one reappears on screen.
-(void)viewDidAppear:(BOOL)animated
{
UIAlertView * alertForCoordinate=[[UIAlertView alloc]initWithTitle:#"Coordinate" message:[NSString stringWithFormat:#"latitude==>%f\nlongitude==>%f",self.userLocation.coordinate.latitude,self.userLocation.coordinate.longitude] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
alertForCoordinate.tag = 1;
[alertForCoordinate show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0 && alertView.tag == 1) {
[SVGeocoder reverseGeocode:CLLocationCoordinate2DMake(self.userLocation.coordinate.latitude, self.userLocation.coordinate.longitude)
completion:^(NSArray *placemarks, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (placemarks.count>0)
{
CLPlacemark * placemark=[placemarks objectAtIndex:0];
currentLocationUpcoming =[placemark locality];
/*****************Second Alert******************/
UIAlertView * alert=[[UIAlertView alloc]initWithTitle:#"Location" message:[NSString stringWithFormat:#"currentLocation==>%#",currentLocationUpcoming] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[self.eventsTableView reloadData];
}
}];
}
}
i had same issue "UIAlertView Shows two times", but in my case it was because of coding error with long press gesture recognizer (different than original question, but may be useful for other folks that google uialertview showing twice). inside method to handle long press, i called method to show UIAlertView. my mistake was not recalling that handle long press method gets called twice each time user long presses (once for press and hold down, once when user releases their finger). the correct code recognizes gesture state (code below).
-(IBAction)handleHoldOnContact:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateBegan){
// NSLog(#"UIGestureRecognizerStateBegan hold");
//Do Whatever You want on Began of Gesture
// ...
} else if (sender.state == UIGestureRecognizerStateEnded) {
// NSLog(#"UIGestureRecognizerStateEnded release");
//Do Whatever You want on End of Gesture
// ...
}
}
I too get the same issue. To overcome this problem, i done the following things. Get the alertview as global variable. And then,
if(!alertForCoordinate){
alertForCoordinate=[[UIAlertView alloc]initWithTitle:#"Coordinate" message:[NSString stringWithFormat:#"latitude==>%f\nlongitude==>%f",self.userLocation.coordinate.latitude,self.userLocation.coordinate.longitude] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil,nil];
[alertForCoordinate show];
}
After that, when you clicking "OK" button from the Alertview. set that to nil. Like the following,
alertForCoordinate = nil;
Hope, this will help you.
It could be a case of duplicating a button, and therefore it's IBaction references, in main.storyboard.
I had a button that was styled perfectly in main.storyboard, so I alt drag duplicated it and attached a new IBaction to the viewController. I didn't realize it but when I tapped that new button it fired the IBaction for both the first button and the second button, because it was hooked up to both, as it was a duplicate of the first.
I right clicked the second button in main.storyboard, saw the reference to the IBaction from the first button AND the second, then deleted the reference to the first. Problem solved. What a nightmare. Hope this helps someone.

How to hook UIAlertView to actions?

I am creating a drawing application where the user can draw using their finger strokes. I am trying to make a button that asks the user if they would like to clear the canvas. This alert has two buttons "Yes" and "No". I have the alert view appearing correctly but I have spent all day trying to figure out how to hook the buttons up to actions. I have so far had no success even after reading and watching from many instructional sources. From everything that I have read I can't understand why it would not be working. I have included UIAlertViewDelegate in my .h file also.
Here is my alert view:
- (IBAction)clearButton:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Clear Canvas"
message:#"Are you sure?"
delegate:nil
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
Here is my clear canvas method:
- (void)clearCanvas:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1)
drawImage.image = nil;
}
Any help or pointers would be greatly appreciated! I'm self taught and still very much a beginner!
Thanks!
- (IBAction)clearButton:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Clear Canvas"
message:#"Are you sure?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
Notice the difference in the delegate parameter. You must conform to the delegate you have declared in the .h
Secondly, use the delegate method -alertView:clickedButtonAtIndex

UIAlertView keyboard doesn't get shown unless app is re-opened

When the user opens my app, I want to check for a value stored in the defaults, and if it is not present prompt the user to input a value. The storing/reading of the value appears to be working.
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"Checking if there is an email address set");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString * emailAddress = [defaults objectForKey:#"emailAddress"];
if (IsEmpty(emailAddress))
{
NSLog(#"email address is blank, prompting user to enter one..");
self.emailPromptAlert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Enter Email address:"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[self.emailPromptAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[self.emailPromptAlert setTag:1];
[self.emailPromptAlert show];
}
}
The problem that I have, is when I do a clean install of my app and load for the first time, the alert shows up as expected but there is no keyboard shown, so the user can't actually type anything.
Clicking the home button then bringing the app back into the foreground again, the same alert is on screen but this time the keyboard is actually showing.
What can I do to make sure the keyboard gets shown the first time?
That's a weird behavior, Why don't you try showing the alert in the next runloop
[self.emailPromptAlert performSelector:#selector(show) withObject:nil afterDelay:0];
I had the same problem. In my case, the keyboard was already visible at the time that I showed the alert. I resolved it by dismissing the keyboard before showing the alert:
[myTextField resignFirstResponder];
[myAlert show];
I am not totally sure, but maybe this could work?
self.emailPromptAlert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Enter Email address:"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
[self.emailPromptAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
[self.emailPromptAlert setTag:1];
[self.emailPromptAlert show];
//try this?
UITextField *textField = [self.emailPromptAlert textFieldAtIndex:0];
[textField becomeFirstResponder];
This doesn't really get to the root of the problem of why it isn't showing in the first place, but it could be a solution.

Resources