iPhone:默认情况下隐藏UITableView搜索栏

Tim*_*Tim 85 iphone user-interface uitableview ios

我使用Interface Builder创建了一个表视图,我在其中添加了库的搜索栏和搜索显示控制器以添加搜索功能.但是,IB会对其进行设置,以便在首次显示视图时在屏幕顶部显示该栏.

我想知道如何在默认情况下隐藏搜索栏,但仍可以使用表格视图滚动(请参阅Apple的Mail应用程序中的示例).我已经打过电话scrollRectToVisible:animated:viewDidLoad滚动表中查看了下来,但无济于事.隐藏搜索栏的首选方法是什么?

Zar*_*ony 115

首先要确保将UISearchBar添加到UITableView的tableHeaderView中,以便它与表的内容一起滚动,并且不会固定到视图的顶部.

搜索栏不计入tableview中的一行,因此如果您将tableview的顶部滚动到第一行,它会"隐藏"搜索栏:

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
Run Code Online (Sandbox Code Playgroud)

或者在Swift中:

yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
Run Code Online (Sandbox Code Playgroud)

确保在包含数据之前不滚动tableview(scrollToRowAtIndexPath如果给定的indexPath没有指向有效行,则会引发异常(即如果tableview为空)).

  • 蒂姆,这是要走的路!我使用了self.tableView.contentOffset = CGPointMake(0,self.searchDisplayController.searchBar.frame.size.height); (106认同)
  • 我找到了一种方法:而不是滚动到索引路径,将表的滚动视图的内容偏移更改为0.0,44.0的CGRect (18认同)
  • 实际上,我遇到的问题是,如果没有足够的行来填充屏幕,表视图将不会滚动 - 在一行或两行中,此代码不执行任何操作.这是预期的行为吗?我可以以某种方式绕过它吗? (12认同)

ban*_*isa 45

不要将UISearchBar添加为UITableView的子视图,这不是必需的.

UITableView有一个tableHeaderView属性,非常适合这个:

- (void) viewDidLoad {
    [super viewDidLoad]; 
    self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
    self.searchBar.showsCancelButton = YES;    
    self.searchBar.delegate = self;
    self.tableView.tableHeaderView = self.searchBar;     
}
Run Code Online (Sandbox Code Playgroud)

如果您不希望默认看到它:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView setContentOffset:CGPointMake(0, 44)];
}
Run Code Online (Sandbox Code Playgroud)

我也得到取消按钮再次隐藏它....(并删除键盘)

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
    [self.searchBar resignFirstResponder];
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说效果很好,但是我建议在viewWillAppear中使用self.tableView.tableHeaderView.frame.size.height而不是硬编码44,以允许Apple将来可能对搜索栏高度进行更改. (3认同)

And*_*rei 25

Tim和Joe D'Andrea在评论中注明了contentOffset,但通过添加动画来隐藏搜索栏,这有点扩展了.我注意到搜索栏消失后有点出乎意料.

想要针对iOS 4.0及更高版本的用户进行一点更新,请尝试以下操作:

[UIView animateWithDuration:0.4 animations:^{
    self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
 } completion:nil];
Run Code Online (Sandbox Code Playgroud)

上一个答案:

[UIView beginAnimations:@"hidesearchbar" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];

self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);

[UIView commitAnimations];
Run Code Online (Sandbox Code Playgroud)

  • 我发现动画是这个解决方案的关键.尝试在没有动画的情况下设置内容偏移似乎什么都不做.然而,我发现只需调用[self.tableView setContentOffset:CGPointMake(0,44)animated:TRUE]就可以了,而不是使用此示例中的动画方法(或块). (9认同)
  • 如果你在`viewDidAppear:`而不是`viewDidLoad`中实现它,我已经成功了,而不需要动画. (5认同)

cod*_*nja 7

这个解决方案有很多答案,但是对我来说都不是很好.

这非常有效.没有动画,并且完成了-viewDidLoad

 - (void)viewDidLoad {
     [super viewDidLoad];
     self.tableView.contentOffset = CGPointMake(0,  self.searchBar.frame.size.height - self.tableView.contentOffset.y);
 }
Run Code Online (Sandbox Code Playgroud)

注意:

代码假定您具有searchBar @property链接到搜索栏的内容.如果没有,您可以self.searchDisplayController.searchBar改用


Das*_*oga 6

适用于Swift 3+

我这样做了:

声明var:

    var searchController = UISearchController()
Run Code Online (Sandbox Code Playgroud)

并在viewDidLoad()方法中

    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = true
    searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height)
Run Code Online (Sandbox Code Playgroud)


Hot*_*ard 5

我的目标是在加载视图控制器时隐藏添加到在Storyboard中的普通TableView样式的tableHeaderView中的搜索栏,并在用户向下滚动到UITableView顶部时显示栏.所以,我正在使用Swift并添加了扩展名:

extension UITableView {
    func hideSearchBar() {
        if let bar = self.tableHeaderView as? UISearchBar {
            let height = CGRectGetHeight(bar.frame)
            let offset = self.contentOffset.y
            if offset < height {
                self.contentOffset = CGPointMake(0, height)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

viewDidLoad()中只需调用:

self.tableView.hideSearchBar()
Run Code Online (Sandbox Code Playgroud)


Bri*_*ian 5

当没有足够的行来填充 tableView 时,所有现有的解决方案在 iOS 8 上都不适用于我,因为在这种情况下,iOS 会自动调整插图。(虽然有足够的行,但现有答案很好)

在这个问题上浪费了大约 6 个小时之后,我终于得到了这个解决方案。

简而言之,如果没有足够的单元格,您需要将空单元格插入 tableView,因此 tableView 的内容大小足够大,iOS 不会为您调整 inset。

这是我在 Swift 中的做法:

1.) 将变量声明minimumCellNum为类属性

var minimumCellNum: Int?
Run Code Online (Sandbox Code Playgroud)

2.)计算minimumCellNum并设置tableView.contentOffsetviewWillAppear

let screenHeight = Int(UIScreen.mainScreen().bounds.height)

// 101 = Height of Status Bar(20) + Height of Navigation Bar(44) + Height of Tab Bar(49)
// you may need to subtract the height of other custom views from the screenHeight. For example, the height of your section headers.
self.minimumCellNum = (screenHeight - 103 - heightOfOtherCustomView) / heightOfYourCell
self.tableView.contentOffset = CGPointMake(0, 44)
Run Code Online (Sandbox Code Playgroud)

3.) 在 tableView(tableView: UITableView, numberOfRowsInSection section: Int))

let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
    return numOfYourRows
} else {
    return minimumCellNum!
}
Run Code Online (Sandbox Code Playgroud)

4.)在 storyboard 和 in 上注册一个空单元格,其selection属性为NonetableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)

if indexPath.row < numOfYourRows {
    return YOUR CUSTOM CELL
} else {
    let cell = tableView.dequeueReusableCellWithIdentifier("EmptyCell", forIndexPath: indexPath) as! UITableViewCell
    return cell
}
Run Code Online (Sandbox Code Playgroud)

5.) 在 tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

if tableView == self.tableView {
    if numOfYourRows < (indexPath.row + 1) {
        return
    }
    YOUR LOGIC OF SELECTING A CELL
}
Run Code Online (Sandbox Code Playgroud)

这不是一个完美的解决方案,但它是唯一在 iOS 8 上真正适用于我的解决方法。我想知道是否有更简洁的解决方案。