1

Im trying to add a UIAlertView to warn the user that the link will open in Safari. The user can then choose OK(open the url) or cancel which should just close the alert and return to the links. I have three different UIButtons which has 3 different URLs.

Right now ive added a IBAction to all buttons and all buttons has Tags (which i think i can use somehow :D). I guess - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: delegate will be good to use to..

My question: how should the UIAlertView know what URL to open i user clicks ok?

saadnib
  • 11,145
  • 2
  • 33
  • 54
tobbe
  • 1,737
  • 6
  • 23
  • 40

3 Answers3

1

I suggest that you use a subclass of UIAlertView that is able to track some more properties along. I do this in all my projects and it is much simpler.

  • One solution to do this would be to subclass UIAlertView to MyAlertView and add a @property(nonatomic, retain) id userInfo; or @property(nonatomic, retain) NSURL* urlToOpen. Thus you can attach custom data to your UIAlertView and retrieve it in the delegate method to do whatever you need with it.
  • Another solution, and my preferred one actually, is to add Objective-C blocks support to UIAlertView, to be able to use UIAlertView using the blocks API instead of using a delegate. This is particularly useful if you use multiple UIAlertViews in the same class and with the same delegate, as using a single delegate to handle the different instances is a mess.

I personally use this technique all the time, as it also makes my code more readable by having the code that executes when the button is tapped right next to the code that shows the alert, instead of having it at a complete different places when you use delegate methods.

You can look at my OHAlertView subclass here on GitHub that implement this already. The usage is really simple and allow you to use blocks for each alert view instead of a common delegate, see below.


Usage Example

-(void)confirmOpenURL:(NSURL*)url
{
  NSString* message = [NSString string WithFormat:@"Open %@ in Safari?",
                                                  url.absoluteString];
  [OHAlertView showAlertWithTitle:@"Open URL"
                          message:message
                     cancelButton:@"No"
                         okButton:@"Yes"
                   onButtonTapped:^(OHAlertView* alert, NSInteger buttonIndex)
  {
    if (buttonIndex != alert.cancelButtonIndex)
    {
       // If user tapped "Yes" and not "No"
       [[UIApplication sharedApplication] openURL:url];
    }
  }];
}

Then each button can have its own action:

-(IBAction)button1Action
{
  [self confirmOpenURL:[NSURL URLWithString:@"http://www.google.com"]];
}
-(IBAction)button2Action
{
  [self confirmOpenURL:[NSURL URLWithString:@"http://www.stackoverflow.com"]];
}

Or you can have a common IBAction for all your buttons opening URLs:

-(IBAction)commonButtonAction:(UIButton*)sender
{
   NSUInteger tag = sender.tag;
   NSString* urls[] = { @"http://www.google.com", @"http://www.stackoverflow.com" };
   NSURL* buttonURL = [NSURL URLWithString: urls[tag] ]; // in practice you should check that tag is between 0 and the number of urls to be sure, that's just an example here
   [self confirmOpenURL:buttonURL];
}
AliSoftware
  • 32,623
  • 6
  • 82
  • 77
  • thanks! that did help me solve it but was a little to advanced for me. Did it an even easier way hehe – tobbe Sep 14 '12 at 14:26
  • Actually as can understand that creating a class that implements blocks can be a bit advanced for a beginner, but as I already created the class for you, I don't see what is complicated in using it directly (see my example, you just have to copy/paste it)… ;) – AliSoftware Sep 14 '12 at 14:56
1

Solved it like this: added a tag when creating the UIAlertView. Like this:

- (IBAction)PressedButton {

    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Link"
                                                      message:@"Want to open in safari?"
                                                     delegate:self
                                            cancelButtonTitle:@"Ok"
                                            otherButtonTitles:nil];

    message.tag = 2;        //different tag for each button

    [message addButtonWithTitle:@"Cancel"];
    [message show];

}

Then when - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex delegate was thrown I did this:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

    if (buttonIndex == alertView.cancelButtonIndex){

        if (alertView.tag == 1)
        {
            //go to URL1
        }

        else if (alertView.tag == 2)
        {
             //go to URL2
        }

        else if (alertView.tag == 3)
        {
            //go to URL3
        }

    }
}
tobbe
  • 1,737
  • 6
  • 23
  • 40
0

Your button action method should have a signature like this:

 -(void)doSomething:(id)sender;

whereby sender will be the button. Based on this you could find out which URL is meant.

sergio
  • 68,819
  • 11
  • 102
  • 123