Changing the size of the UISearchBar TextField?

2019-01-03 23:16发布

I have a UITableView with an Index on the side; I want to add a UISearchBar to it, but the index overlaps with the "x" to clear the search. I've noticed in the Contacts application, the textfield within the UISearchBar is resized to accommodate this, but I can't work out how to do this in my own app.

I have tried the following in my viewDidLoad, but it does not seem to work.

UITextField * textField = (UITextField *)[[self.search subviews] objectAtIndex:0];
CGRect r = textField.frame;

[textField setFrame:CGRectMake(r.origin.x, r.origin.y, r.size.height, r.size.width-30)];

Any ideas?

17条回答
Emotional °昔
2楼-- · 2019-01-03 23:36

it's much easier than all these suggestions. In interface builder, instead of putting the Search Bar as the header of your Table View, you can put a View instead. Then, put a Navigation Bar inside this View. Grab the left resizing handle of the Navigation Bar and pull it to the right until the N B is only 25 pixels wide. Clear out the Title in the N B (double click to select it, then delete). Then, add a Search Bar into the same View. Move its right resizing handle to the left, adjust so that it abuts the N B. That's it.

You can enable a cancel button if you want too and it also won't overlap the index (remains within the search bar).

Apparently a Table View can only have 1 subview in its header, that's why you need to put the View first, then the N B and Search Bar inside it.

UPDATE: see Beginning iPhone Development from Apress, p. 241 of SDK 3 edition. You just disable the index while searching.

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    if (isSearching) {
        return nil;
    }
    return keys;
}

Also they talk about adding a magnifying glass to the top of the index.

Great book all around.

查看更多
家丑人穷心不美
3楼-- · 2019-01-03 23:39

Why not just make the actual UISearchBar smaller horizontally, and place an (empty) UINavigationBar to the right of it? They will render the exact same background.

Better than hacking the internals of Apple's objects that could change.

Also, when animating the UISearchBar's width, you'll notice that the inner text field is not animated along with it. You can fix this by calling UISearchBar's "layoutSubviews" within your animation block after changing its frame. (that's where it determines the size of the inner text field)

查看更多
何必那么认真
4楼-- · 2019-01-03 23:40

Another appraoch (though tedious) would be to resize the search bar and fill the 'gap' with a navigation bar. Works for me.

查看更多
神经病院院长
5楼-- · 2019-01-03 23:41

I am using ViewDeck and want to show a UISearchbar inside the leftController.

Now the problem is if I open the left side which contains the navigation, the right bit overlaps my search field.

I got rid of this by over writing UISearchBar, the textfield will always have the same width, but in one case there is the ViewDeck overlapping and in the other case I hide the ViewDeck-bit and then the cancel button will take up the space:

Subclassing UISearchBar

#import "ViewDeckSearchBar.h"
#define kViewDeckPadding 55

@interface ViewDeckSearchBar()
@property (readonly) UITextField *textField;
@end

@implementation ViewDeckSearchBar

static CGRect initialTextFieldFrame;

- (void) layoutSubviews {

    [super layoutSubviews];

    // Store the initial frame for the the text field
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        initialTextFieldFrame = self.textField.frame;
    });

    [self updateTextFieldFrame];
}

-(void)updateTextFieldFrame{

    int width = initialTextFieldFrame.size.width - (kViewDeckPadding + 6);
    CGRect newFrame = CGRectMake (self.textField.frame.origin.x,
                                  self.textField.frame.origin.y,
                                  width,
                                  self.textField.frame.size.height);

    self.textField.frame = newFrame;
}

-(UITextField *)textField{
    for (UIView *view in self.subviews) {
        if ([view isKindOfClass: [UITextField class]]){
            return (UITextField *)view;
        }
    }

    return nil;
}

@end

ViewController class

In my Navigation class I need to overwrite these two UISearchbarDelegate methods in order to go to fullscreen with the search results:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{

    [self.viewDeckController setLeftSize:0];

    // I am also using scopes, which works fine (they fade out when not searching)
    self.searchBar.scopeButtonTitles = @[@"Food",
                                         @"Beverages",
                                         @"Misc"];
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
    self.viewDeckController.leftSize = 55;
}

Result

ViewDeck showing to the right:

a http://i5.minus.com/jA34MnXVqPZez.png

Search in Fullscreen (The button and the scope buttons are animated in).

a http://i2.minus.com/jjKEgXLur1kH6.png

查看更多
放我归山
6楼-- · 2019-01-03 23:44

Sorry for Necroposting, but I found another way to make a little space on the right of the textfield. I was having the problem, that I had an indexed tableview with a searchbar as the first row. Now the index and the searchbar (made in IB, btw.) were overlapping. It tried almost everything with no success. It seems that the width and height properties of the textifield don't respond... So I came up with this:

searchBar.showsCancelButton = YES;

UIView *cButton = [searchBar.subviews objectAtIndex:2];

cButton.hidden = YES;

I still can't adjust the size of the space, but this does it for now... although... pretty weird solution...

查看更多
狗以群分
7楼-- · 2019-01-03 23:47

The key is to use the "Search Bar and Search Display Controller" and not the "Search Bar" when using Interface Builder.

查看更多
登录 后发表回答