views:

306

answers:

1

I am trying to implement an autocomplete text field for the iPhone/iPad. I have subclassed a UITextField. As a user enters search criteria, if the search string matches some entity in our database, then that entity becomes part of the user's search criteria and I want to append a button representing that entity to the leftView property of the text field. That way as the user enters more search criteria, items are appended to the left view, in a similar way to the mail composer when entering contacts into the to/cc fields.

My problem is that the leftView does not show anything. I can increase the size of the leftView by setting the frame property on the leftView. But any subViews I add (for example an UIImageView or a UIButton), do NOT show up in the left view of the text field. The cursor of the text field does move to the right as I add subviews to the left view and set the frame of the left view, but nothing is visible.

I create a new UIView and set the leftView to that view.

Then I create new UIButton objects and add those as subviews to the leftView.

I set the frames of the buttons and the leftview in layoutSubviews.

The leftView definitely increases in size and the text field cursor moves to the right as it should.

But, none of the buttons show up (the are not visible).

There must be something about leftView that I dont understand.

Here is code snippet:

    // add search criteria to the left view 
// this will create a button on the left side of the text field
(void) addSubValue:(NSString*) value display:(NSString*)display
{
    if(subValues==nil)
    {
        NSMutableArray * tmp=[[NSMutableArray alloc] init];

        self.subValues=tmp;

        [tmp release];
    }

    AutocompleteSubValue * subValue =[[AutocompleteSubValue alloc] init];

    subValue.value=value;
    subValue.display=display;

    UIButton * button=[UIButton buttonWithType:UIButtonTypeRoundedRect];

    button.frame=CGRectMake(0, 0, 100, 30); // this frame gets reset later in layoutSubviews...
    button.titleLabel.text=display;
    button.titleLabel.textColor=[UIColor whiteColor];
    button.titleLabel.backgroundColor=[UIColor blueColor];
    button.backgroundColor=[UIColor blueColor];

    [button addTarget:self action:@selector(touchSubValue:) forControlEvents:UIControlEventTouchUpInside];

    subValue.view=button;

    [self.leftView addSubview:button];


    [subValues addObject:subValue];
    [subValue release];

    [self setNeedsLayout];
}

(void) touchSubValue:(id)sender
{
    UIButton * button=sender;
    // find value user touched and remove from the search
    AutocompleteSubValue * subValue;
    for (AutocompleteSubValue * s in subValues)
    {
        if([s.view isEqual:button])
        {
            subValue=s;
            break;
        }
    }
    if(subValue)
    {
        [button removeFromSuperview];
        [subValues removeObject:subValue];
    }
}

(void)layoutSubviews
{
    if(self.leftView==nil)
    {
        UIView * view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; // this views frame gets reset in layoutSubviews
        self.leftView = view;
        self.leftViewMode = UITextFieldViewModeAlways;
        [view release];
    }

    CGFloat left=30;

    // set frames of sub values
    for (AutocompleteSubValue * subValue in subValues)
    {
        CGFloat display_width=100+16; // TODO: get from display text

        CGFloat height=30;

        CGRect frame=CGRectMake(left, 4, display_width, height);

        subValue.view.frame=frame;

        left+=display_width+10;
    }

    // set width of left view to make room for buttons, and move cursor to the right
    self.leftView.frame=CGRectMake(self.leftView.frame.origin.x, self.leftView.frame.origin.y, left, self.leftView.frame.size.height);

    [self.leftView layoutSubviews];
}
A: 

I figured this out. I was not calling [super layoutSubviews] in the layoutSubviews override. Now it renders the subviews of the leftview correctly. Before, I was just calling [leftView layoutSubviews] in layoutSubview but that did not work.

Robert Stewart