answering an old question here but i was struggling with this one myself recently and found some shortcomings with the other answers for the situation i was trying to address. here's what i did in a subclass of UISearchBar:
first add a UIButton property (here "selectButton"). then override the initWithFrame method and do something similar to the following:
-(id)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame])
{
self.selectButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.selectButton.contentEdgeInsets = (UIEdgeInsets){.left=4,.right=4};
[self.selectButton addTarget:self action:@selector(pressedButton:) forControlEvents:UIControlEventTouchUpInside];
self.selectButton.titleLabel.numberOfLines = 1;
self.selectButton.titleLabel.adjustsFontSizeToFitWidth = YES;
self.selectButton.titleLabel.lineBreakMode = UILineBreakModeClip;
[self addSubview:self.selectButton];
[self.selectButton setFrame:CGRectMake(5, 6, 60, 31)];
}
return self;
}
Now you want to override the layout subviews method to resize the searchbar to the appropriate width, depending on whether or not the cancel button is showing. That should look something like this:
-(void)layoutSubviews
{
[super layoutSubviews];
float cancelButtonWidth = 65.0;
UITextField *searchField = [self.subviews objectAtIndex:1];
if (self.showsCancelButton == YES)
[searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70 - cancelButtonWidth, 31)];
else
[searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70, 31)];
}
Note that in the above method I added a constant for the cancelButtonWidth. I tried adding code to get the width from [self cancelButton] but that seems only accessible at runtime and doesn't allow the project to compile. In any case this should be a good start for what you need