Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

2 of the same UI Alert Views showing up at the same time

In my app I am asking the user to provide a web link and if the link is valid then the user may proceed to the next view. If not I then cancel the segue and try to pop an alert view. My main problem is that I always have 2 of the same alerts popping up even though the [show alert] method is called once. Anyone have any idea why I get 2 alerts showing up at the same time? To dismiss it the user has to press ok twice. Any feedback will be greatly appreciated!!

Shown below is my code:

<p>
// .m

// Segue cancel method and url checker
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    self.urlString = self.textView.text;
    self.url = [NSURL URLWithString:self.urlString];
    NSLog(@"URL Value: %@", self.url);
    NSLog(@"String Value: %@", self.urlString);
    if ([self.urlString length] == 0) {
        //cancel transition
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Need to enter something bud.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
        return NO;
    } else if (self.url == nil) {
        //cancel transition
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Invalid!" message:@"Make sure that the web link is valid.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
        return NO;
    } else {
        return YES;
    }
}

#pragma mark - IBActions

- (IBAction)next:(id)sender {
    [self shouldPerformSegueWithIdentifier:@"showShareFriends" sender:self];
}
</p>

2 Answers

its possible the segue is being performed twice. but looking at your next action I see you are calling shouldPerformSegue with identifier. im not very familiar with using that method, but it seems to me like that method gets called anytime performSegueWithIdentifier is called and if it returns yes the segue is performed and if it returns NO the segue is ignored. im not sure you are supposed to call that method yourself. try replacing that with

- (IBAction)next:(id)sender {
    [self performSegueWithIdentifier:@"showShareFriends" sender:self];
}

and see what happens. honestly it may be better to just not even implement the shouldPerform method and just put the UIAlertView logic in the action itself.

//only perform the segue if self.UrlString and self.url have valid values
- (IBAction)next:(id)sender {

if ([self.urlString length] == 0) {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Need to enter something bud.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];

    } else if (self.url == nil) {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Invalid!" message:@"Make sure that the web link is valid.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];

    } else {
         [self shouldPerformSegueWithIdentifier:@"showShareFriends" sender:self];
    }

}

Hi Stone, thanks so much for the feedback. I had tried your code and the first code does not work as "performSegueWithIdentifier" pushes it to the next view controller no matter what the condition is. The second code you suggested works well and fixes the problem. : )

Although going and testing my project even further I had found that the segue & method was in fact called twice. It gets called once no matter what when I select the IBAction "Next". This was because I had created the segue from the button within the view controller via StoryBoard. When I deleted the segue and created a new one from the view controller itself rather than choosing the button inside it (IBAction "next") the result was UIAlert only popping out once! : D

After all this testing I had decided to keep the UI alert within the "shouldPerformSegueWithIdentifier" and keep my storyboard segue start from the view controller instead of the IBAction Next. Doing it this way makes the code easier for me and you only need to create 1 pair of if/else conditions rather than one on IBAction (for alert view) and one on shouldPerformSegueWithIdentifier (for segue handling) to check for the url and urlString.

cool glad its working

hmm yeah dont see anything there that would cause 2 of them to appear. can you post your full view controller file?

Hi Stone, thanks for the feedback. I think it might have something to do with the "shouldPerformSegueWithIdentifier" method as before using that method I had the exact same [alertview show] and url checking method placed in IBAction. The alert view had only shown once like it's supposed to. However once I started using the method and moved my UI alert view and if statements to the "shouldPerformSegueWithIdentifier" method, two alert views started popping up. Another note I might add is that I created the segue using storyboard feature and not by code. (Is it possible that the segue is being called twice?)

Anyway shown below is my whole .h and .m file for the view controller.

<p>
//. h
#import <UIKit/UIKit.h>

@interface JWFShareURLViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (strong, nonatomic) NSString *urlString;
@property (strong, nonatomic) NSURL *url;

- (IBAction)next:(id)sender;

@end


// .m
#import "JWFShareURLViewController.h"
#import "JWFShareTableViewController.h"

@interface JWFShareURLViewController ()

@end

@implementation JWFShareURLViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

// Passing URL to the next view controller
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showShareFriends"]) {
        JWFShareTableViewController *viewController = (JWFShareTableViewController *)segue.destinationViewController;
        viewController.url = self.url;
        viewController.urlString = self.urlString;
    }
}

// Segue cancel method and url checker
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    self.urlString = self.textView.text;
    self.url = [NSURL URLWithString:self.urlString];
    NSLog(@"URL Value: %@", self.url);
    NSLog(@"String Value: %@", self.urlString);
    if ([self.urlString length] == 0) {
        //cancel transition
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Oops!" message:@"Need to enter something bud.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
        return NO;
    } else if (self.url == nil) {
        //cancel transition
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Invalid!" message:@"Make sure that the web link is valid.." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
        return NO;
    } else {
        return YES;
    }
}

#pragma mark - IBActions

- (IBAction)next:(id)sender {
    [self shouldPerformSegueWithIdentifier:@"showShareFriends" sender:self];
}
@end
</p>

Thanks again for the feedback. : )