Monday, May 11, 2009

UISearchBar like Contacts

This is the inaugural posting for this blog, and I picked a topic that I have seen many times on the discussion forums in the past, and one I solved for myself last fall.

When using a UISearchBar with an indexed table view, the index will get written on top of the search field in the search bar, resulting in an ugly UI that hopefully no one would ever inflict on their users.

To solve the problem, I have subclassed UISearchBar and overridden the layoutSubviews method to draw differently when there is an index. When I am using an indexed table with search, I just set the hasIndex attribute to YES. Here is the code :

- (void)layoutSubviews {
[super layoutSubviews];
BOOL hasButton = NO;
if (hasIndex) {
UITextField *aSearchField = nil;
for (UIView *aView in [self subviews]) {
if ([aView isKindOfClass:[UITextField class]]) {
aSearchField = (UITextField *)aView;
} else if ([aView isKindOfClass:[UIButton class]]) {
hasButton = YES;
}
}
if (aSearchField && !hasButton) {
aSearchField.frame = CGRectMake(aSearchField.frame.origin.x, aSearchField.frame.origin.y, aSearchField.frame.size.width -30, aSearchField.frame.size.height);
}
}
}

The code checks for our hasIndex attribute, and if it is true, changes the layout of the search bar by removing 30 pixels from the right-hand side of the search text field. If there is a Cancel button on the search field, we do nothing.

2 comments:

  1. Thanks David. I've been looking for a clean way to handle this. This worked perfectly!

    ReplyDelete
  2. Nice solution.

    Rather than add a new instance (hasIndex) that one has to remember to set, you can use something like

    BOOL hasIndex = [self.delegate respondsToSelector:@selector(sectionIndexTitlesForTableView)];

    ReplyDelete