0

I've been racking myself on this one for a while, and can't figure it out.

It is an action sheet that bookmarks a page (for a safari like app) When I hit Okay, i get the -[UIThreePartButton text]: unrecognized selector at instance XXXX

I can't seem to step through where my pain is.

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0) 
    {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Bookmarks" message:@"Please enter the site name: \n \n \n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
        alert.center=CGPointMake(160, 50);
        alert.tag=1;

        UITextField *siteName=[[UITextField alloc]initWithFrame:CGRectMake(20, 70, 245, 30)];
        siteName.backgroundColor=[UIColor clearColor];
        siteName.borderStyle=UITextBorderStyleRoundedRect;
        siteName.autocorrectionType=UITextAutocorrectionTypeNo;
        siteName.delegate=self;
        siteName.clearButtonMode=UITextFieldViewModeWhileEditing;
        siteName.text=[[mainDelegate.sitesArray objectAtIndex:tag] objectForKey:@"webSite"];
        siteName.returnKeyType=UIReturnKeyDone;
        siteName.tag=2;
        [alert addSubview:siteName];

        [alert show];
    } 
}

I realized that it dies on the alert view method below it:

if(alertView.tag==1)
    if (buttonIndex==1)
    {
        if(((UITextField*)[alertView.subviews objectAtIndex:4]).text==@""||((UITextField*)[alertView.subviews objectAtIndex:4]).text==nil)
        {

Spefically on the if(((UITextField*)[alertView.subviews objectAtIndex:4])

I have 4 buttons/action on that action sheet, and the rest are good to go...

Andy Obusek
  • 12,614
  • 4
  • 41
  • 62
Jason
  • 31
  • 4
  • When you place a breakpoint on exceptions and turn breakpoints on, which line does your application halt on? – Brad Larson Dec 10 '10 at 15:29
  • f(alertView.tag==1) if (buttonIndex==1) { if(((UITextField*)[alertView.subviews objectAtIndex:4]).text==@""||((UITextField*)[alertView.subviews objectAtIndex:4]).text==nil) { – Jason Dec 10 '10 at 15:43

2 Answers2

2

Do not try to manually traverse the view hierarchy of a UI element that Apple does not otherwise document. Doing something like [alertView.subviews objectAtIndex:4] is dangerous, because you end up having to make a blind assumption of the internal structure of a UIAlertView.

In this case, you're hitting the wrong element (a UIThreePartButton) and crashing your application with an exception. Even if you do get the index correct on where your text field is right now, there's no guarantee that Apple won't change the view number or ordering in a future OS release, suddenly causing all installations of your application to crash.

To prevent this, hold on to a reference to your UITextField so you don't need to probe the view hierarchy on a UIAlertView.

Even better, don't use an alert view for text input, but a custom modal view. Alerts really should be reserved for infrequent error displays or other critical updates. From the iOS Human Interface Guidelines:

The infrequency with which alerts appear helps users take them seriously. Be sure to minimize the number of alerts your app displays and ensure that each one offers critical information and useful choices.

As an FYI, you're also leaking your siteName UITextField in the above code, and potentially your UIAlertView.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
0

If you have 4 buttons per action would your objectAtIndex not be 3 instead of 4? Seems like you are getting an out of bounds exception.

Specifically objectAtIndex:4 will generate an exception if there are 4 items in the array since the last valid index is 3.

DigitalBytes
  • 149
  • 3
  • yeah, i've been thinking that...but the error seems to be at: – Jason Dec 10 '10 at 15:54
  • alertView.subviews objectAtIndex:4 So, i think the 4 isn't asking about the butten index, but hte view index. I may be off my views somehow – Jason Dec 10 '10 at 15:55