更改UISearchBar TextField的大小?

时间:2009-02-17 13:38:32

标签: iphone search uitableview

我有一个带有索引的UITableView;我想为它添加一个UISearchBar,但索引与“x”重叠以清除搜索。我已经注意到在联系人应用程序中,UISearchBar中的文本字段被调整大小以适应这一点,但我无法弄清楚如何在我自己的应用程序中执行此操作。

我在viewDidLoad中尝试过以下操作,但它似乎无法正常工作。

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)];

有什么想法吗?

18 个答案:

答案 0 :(得分:30)

比所有这些建议容易得多。在界面构建器中,您可以放置​​View,而不是将搜索栏作为表视图的标题。然后,在此视图中放置导航栏。抓住导航栏的左侧调整大小手柄并将其向右拉,直到N B仅为25像素宽。清除N B中的标题(双击选择它,然后删除)。然后,将搜索栏添加到同一视图中。将其右侧调整大小手柄向左移动,调整使其与N B相邻。就是这样。

您可以根据需要启用取消按钮,也不会与索引重叠(保留在搜索栏中)。

显然,表格视图的标题中只能有1个子视图,这就是你需要先放置视图,然后放入N B和搜索栏的原因。

更新:请参阅Apress的iPhone开发。 SDK 3版本的241。您只需在搜索时禁用索引。

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

他们还谈到在索引顶部添加放大镜。

周围的好书。

答案 1 :(得分:16)

为什么不将水平的实际UISearchBar缩小,并在其右侧放置一个(空)UINavigationBar?它们将呈现完全相同的背景。

比攻击可能会改变的Apple对象的内部更好。

此外,在动画UISearchBar的宽度时,您会注意到内部文本字段不随其动画。您可以通过在更改其框架后调用动画块中的UISearchBar的“layoutSubviews”来解决此问题。 (这就是确定内部文本字段大小的地方)

答案 2 :(得分:8)

好的,我想出了一个解决方案。

  1. 创建UISearchBar的子类
  2. 在drawRect:方法中包含此代码。

    UITextView * textField = [self.subviews objectAtIndex:0];
    textField.frame = CGRectMake(5, 6, (310 - kRightSideMargin), 31); 
    
    [super drawRect:rect];
    
  3. 注意:kRightSideMargin是我在头文件中设置的常量;我把它设置为25。

    感谢其他人的建议。

答案 3 :(得分:6)

从iOS 6开始,导航栏解决方案对我来说效果不佳,因为现在UISearchBar和UINavigationBar之间的外观略有不同。所以,我通过继承UISearchBar切换到类似于Padraig的方法。

@interface SearchBarWithPad : UISearchBar
@end


@implementation SearchBarWithPad
- (void) layoutSubviews {

    [super layoutSubviews];
    NSInteger pad = 50;
    for (UIView *view in self.subviews) {
        if ([view isKindOfClass: [UITextField class]])
        view.frame = CGRectMake (view.frame.origin.x, view.frame.origin.y, view.frame.size.width - pad, view.frame.size.height);
    }   
}
@end

编辑:啊,我还没试过,但我想你可以设置导航栏的clipToBounds = YES来关闭它的新阴影,从而在两个控件之间再次创建一致的外观。

答案 4 :(得分:6)

正如Padraig所指出的,你要做的就是将searchBar子类化。创建您的UISearchBar子类,并将以下代码添加到layoutSubviews方法中:

- (void)layoutSubviews
{
    UITextField *searchField;

    for(int i = 0; i < [self.subviews count]; i++)
    {
        if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
        {
            searchField = [self.subviews objectAtIndex:i];
        }
    }

    if(!(searchField == nil))
    {
        searchField.frame = CGRectMake(4, 5, 285, 30); 
    }
}

这将循环遍历所有子视图,并根据类型UITextField检查它们。这样一来,如果它在其子视图的排列中移动,这仍然会抓住它。我发现285只是足够宽,不会与我的tableView的索引重叠。

答案 5 :(得分:5)

我正在使用ViewDeck并希望在leftController内显示内的UISearchbar

现在的问题是,如果我打开包含导航的左侧,右侧的位与我的搜索字段重叠。

我通过覆盖UISearchBar来解决这个问题,文本字段将始终具有相同的宽度,但在一种情况下,ViewDeck重叠,在另一种情况下,我隐藏ViewDeck位然后取消按钮将占用空间:

对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类

在我的导航课程中,我需要覆盖这两个UISearchbarDelegate方法,以便使用搜索结果全屏显示:

- (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;
}

结果

ViewDeck显示在右侧:

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

全屏搜索(按钮和范围按钮是动画的)。

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

答案 6 :(得分:2)

只需放置UIView并将搜索栏放在UIView中。 UIView必须与UISearchBar大小相同。 这对我有用。

答案 7 :(得分:2)

很抱歉再拖一遍。

我希望UISearchBar更短,我正在使用UISearchBarController,但实际上并不想要索引。这是因为我右边有一个叠加层:

Long search bar

为此,我伪造了一个带有一个空白项的sectionIndex,然后隐藏它。我是这样做的:

 - (void)hideTableIndex {
    for (UIView *view in [tableView subviews]) {
        if ([view isKindOfClass:NSClassFromString(@"UITableViewIndex")]) {
            view.hidden = YES;
        }
    }
 }

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)aTableView {
    if (aTableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    } else {
        [self performSelector:@selector(hideTableIndex) withObject:nil afterDelay:0];
        return [NSArray arrayWithObjects:@"", nil];
    }
 }

 - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return 0;
 }

这缩短了UISearchBar并隐藏了索引,因此它无法被点击(否则一小部分会移到覆盖的左侧,当点击时会将UITableView滚动到顶部)。像这样:

alt text

最重要的是,当您使用搜索时,仍然可以获得全宽条:

alt text

答案 8 :(得分:1)

对不起Necroposting,但我找到了另一种在文本字段右侧留出一点空间的方法。 我遇到了问题,我有一个索引的tableview,搜索栏是第一行。现在索引和搜索栏(IB,btw。)重叠。它几乎尝试了一切都没有成功。似乎textifield的宽度和高度属性没有响应......所以我提出了这个:

searchBar.showsCancelButton = YES;

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

cButton.hidden = YES;

我仍然无法调整空间的大小,但现在这样做...虽然......非常奇怪的解决方案......

答案 9 :(得分:1)

UISearchBar中使用的文本字段是UITextField的子类,名为UISearchBarTextField。

AFAIK,无法使用公共API调整UISearchBarTextField的大小,private API也没有显示出太多内容。

也许您可以查看UISearchBarTextField的子视图(如果有的话)。

更新:没有。

更新2:我认为你应该看看UITextField的rightView属性。下面的代码虽然不起作用,但似乎是一个很好的起点:

UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[textField setRightView:emptyView];
[textField setRightViewMode:UITextFieldViewModeAlways];
[emptyView release];

答案 10 :(得分:1)

每个人都提供了修改UI的方法。我发现了如何获得相同的结果。您必须提供以下两个实现:

  1. 使用UISearchDisplayController 更重要的是,请确保使用以下命令对其进行初始化:
  2. 
    - (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController
    

    未能设置有效的UISearchBar(或传递nil)将阻止调整索引的UITextField。

    1. 您必须通过以下方式返回有效的标题数组:
    2. 
      - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
      

      如果返回nil,则不会显示索引,并且UITextField将无法正确调整。

      我已经向Apple提交了一份错误报告,暗示似乎合乎逻辑的是只需要#2,而不是#1。我在人机界面指南(iPhone HIG)中找不到任何需要使用UISearchDisplayController的内容。

答案 11 :(得分:1)

使用Interface Builder时,关键是使用“搜索栏和搜索显示控制器”,而不是“搜索栏”。

答案 12 :(得分:0)

我按照Mike的建议制作了一个UIView,然后在其中放置了一个导航栏和UISearch Bar。唯一的问题是第一次显示搜索栏,其背景通常与导航栏相同?

有趣的是,如果我激活搜索,然后点击取消此“固定”的背景!?

我正在使用SDK 3.0,因此我删除了将UISearchDisplayController拖入我的NIB时生成的UISearchBar项目,然后如上所述创建了视图并将其连接到搜索显示中的文件所有者和searchBar插座控制器。

答案 13 :(得分:0)

<link rel="stylesheet" href="/css/redstargames.min.css">

我原来的更改UITextField框架的解决方案在iOS 13中停止工作。将UINavigationBar放在UISearchBar的右侧对我来说从来没有用过,因为它们的顶部和底部外观不同。

答案 14 :(得分:0)

工作正常!!!

  

[searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];

答案 15 :(得分:0)

我想出的并不是太好了。基本上,我使用我想用于搜索栏的框架制作一个空视图。然后我创建一个UIToolbar到搜索栏后面。一定要将其框架设置为与UIView相同的框架,外,Y值必须为-1;否则,您将在顶部绘制两个边框。接下来创建你的UISearchBar,但是将框架的宽度设置为30(或适用于你的应用程序的任何内容)小于UIView。将它们添加为子视图,并将UIView设置为tableHeaderView。

答案 16 :(得分:0)

另一种方法(通过单调乏味)将调整搜索栏的大小并用导航栏填充“空白”。适合我。

答案 17 :(得分:0)

看起来好像Apple调整视图大小(请注意索引在屏幕右侧动画显示),使其大于屏幕。

我想你需要实现searchBarTextDidBeginEditing:的{​​{1}}方法来在适当的时候触发它。然而,这确实有点hacky可能有更好的方法。