ios iPhone:默认隐藏 UITableView 搜索栏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1081381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone: Hide UITableView search bar by default
提问by Tim
I used the Interface Builder to create a table view, to which I added the library's Search Bar and Search Display Controller to add search functionality. However, IB set it up so that the bar is visible at the top of the screen when the view is first displayed.
我使用 Interface Builder 创建了一个表视图,我向其中添加了库的搜索栏和搜索显示控制器以添加搜索功能。但是,IB 对其进行了设置,以便在第一次显示视图时可以在屏幕顶部看到栏。
I'd like to know how to have the search bar be hidden by default but still scrollable with the table view (see Apple's Mail application for an example). I've tried calling scrollRectToVisible:animated:
in viewDidLoad
to scroll the table view down, but to no avail. What's the preferred way of hiding the search bar by default?
我想知道如何在默认情况下隐藏搜索栏,但仍然可以使用表格视图滚动(例如,请参阅 Apple 的邮件应用程序)。我已经打过电话scrollRectToVisible:animated:
中viewDidLoad
滚动表视图下来,但无济于事。默认情况下隐藏搜索栏的首选方式是什么?
回答by Zargony
First make sure, to add the UISearchBar to the tableHeaderView of the UITableView so that it gets scrolled with the table's content and isn't fixed to the top of the view.
首先确保将 UISearchBar 添加到 UITableView 的 tableHeaderView,以便它随着表格的内容滚动并且不会固定到视图的顶部。
The searchbar isn't counted as a row in the tableview, so if you scroll the top of the tableview to the first row, it 'hides' the searchbar:
搜索栏不计为 tableview 中的一行,因此如果您将 tableview 的顶部滚动到第一行,它会“隐藏”搜索栏:
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
or in Swift:
或在斯威夫特:
yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
Make sure to not scroll the tableview before it contains data (scrollToRowAtIndexPath
will raise an exception if the given indexPath does not point to a valid row (i.e. if the tableview is empty)).
确保在包含数据之前不要滚动 tableview(scrollToRowAtIndexPath
如果给定的 indexPath 不指向有效行(即如果 tableview 为空),则会引发异常)。
回答by bandejapaisa
Dont' add the UISearchBar as a subview of the UITableView, this isn't necessary.
不要将 UISearchBar 添加为 UITableView 的子视图,这不是必需的。
The UITableView has a tableHeaderView property that is perfect for this:
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;
}
If you don't want to see it by default:
如果您不想在默认情况下看到它:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView setContentOffset:CGPointMake(0, 44)];
}
I also get the cancel button to hide it again.... (and remove the keyboard)
我也得到取消按钮再次隐藏它......(并移除键盘)
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
[self.searchBar resignFirstResponder];
}
回答by Andrei
The contentOffset was noted in the comments by Tim and Joe D'Andrea, but this is a bit expanded by adding an animation to hiding the search bar. I noticed it is a bit unexpected for the search bar to just disappear.
在 Tim 和 Joe D'Andrea 的评论中提到了 contentOffset,但通过添加动画来隐藏搜索栏,这有点扩展。我注意到搜索栏消失有点出乎意料。
A little update for those who want to target iOS 4.0 and above, try this:
对于那些想要针对 iOS 4.0 及更高版本的人的一些更新,试试这个:
[UIView animateWithDuration:0.4 animations:^{
self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
} completion:nil];
Previous answer:
上一个答案:
[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];
回答by Matej
There are many answers to this solution, however none worked very well for me.
这个解决方案有很多答案,但没有一个对我来说效果很好。
This works perfectly. No animation, and is done upon -viewDidLoad
这完美地工作。没有动画,完成后-viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.contentOffset = CGPointMake(0, self.searchBar.frame.size.height - self.tableView.contentOffset.y);
}
Note:
笔记:
Code assumes you have the searchBar
@property
which is linked to the search bar.
If not, you can use self.searchDisplayController.searchBar
instead
代码假定您拥有searchBar
@property
链接到搜索栏的 。如果没有,您可以self.searchDisplayController.searchBar
改用
回答by Dasoga
For Swift 3+
Swift 3+
I did this:
我这样做了:
Declare this var
:
声明var
:
var searchController = UISearchController()
And in the viewDidLoad()
method
并且在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)
回答by HotJard
My goal was to hide search bar added to tableHeaderView of plain TableView's style in storyboard when the view controller is loaded and show the bar when user scroll down at the top of UITableView. So, I'm using Swiftand has added extension:
我的目标是在加载视图控制器时隐藏添加到情节提要中普通 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)
}
}
}
}
in viewDidLoad()just call:
在viewDidLoad() 中只需调用:
self.tableView.hideSearchBar()
回答by Brian
All existing solutions don't work for me on iOS 8 when there are not enough rows to fill the tableView since iOS will adjust the inset automatically in this situation. (Existing answers are good when there are enough rows though)
当没有足够的行来填充 tableView 时,所有现有的解决方案在 iOS 8 上都不适用于我,因为在这种情况下,iOS 会自动调整插图。(虽然有足够的行,但现有答案很好)
After wasting like 6 hours on this issue, I finally got this solution.
在这个问题上浪费了大约 6 个小时之后,我终于得到了这个解决方案。
In short, you need to insert empty cells into the tableView if there are not enough cells, so the content size of the tableView is big enough that iOS won't adjust the inset for you.
简而言之,如果没有足够的单元格,您需要将空单元格插入 tableView,因此 tableView 的内容大小足够大,iOS 不会为您调整 inset。
Here is how I did it in Swift:
这是我在 Swift 中的做法:
1.) declare a variable minimumCellNum
as a class property
1.) 将变量声明minimumCellNum
为类属性
var minimumCellNum: Int?
2.) calculate minimumCellNum
and set tableView.contentOffset
in viewWillAppear
2.)计算minimumCellNum
并设置tableView.contentOffset
在viewWillAppear
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)
3.) in tableView(tableView: UITableView, numberOfRowsInSection section: Int))
3.) 在 tableView(tableView: UITableView, numberOfRowsInSection section: Int))
let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
return numOfYourRows
} else {
return minimumCellNum!
}
4.) Register an empty cell, whose selection
attribute is None
, on the storyboard and in tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
4.)在 storyboard 和 in 上注册一个空单元格,其selection
属性为None
tableView(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
}
5.) in tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
5.) 在 tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if tableView == self.tableView {
if numOfYourRows < (indexPath.row + 1) {
return
}
YOUR LOGIC OF SELECTING A CELL
}
This is not a perfect solution, but it's the only workaround that really works for me on iOS 8. I'd like to know if there is a neater solution.
这不是一个完美的解决方案,但它是唯一在 iOS 8 上真正适用于我的解决方法。我想知道是否有更简洁的解决方案。
回答by RyanJM
Content offset is the way to go, but it doesn't work 100% of the time.
内容偏移是可行的方法,但它并非 100% 都有效。
It doesn't work if are setting estimatedRowHeight
to a fixed number. I don't know the work around yet. I've created a projectshowing the issue(s) and I've created a radarwith Apple.
如果设置estimatedRowHeight
为固定数字则不起作用。我还不知道周围的工作。我已经创建了一个显示问题的项目,并且我已经与 Apple创建了一个雷达。
Check out the project if you want an example in swift of how to set it all up.
如果您想快速了解如何设置所有项目,请查看该项目。
回答by grep
None of the above worked for me, so just in case if someone will have the same issue.
以上都不适合我,以防万一有人遇到同样的问题。
I have searchBar
set as tableHeaderView
on a grouped table on iOS7. In viewDidLoad
I have tableView.contentOffset = CGPointMake(0, 44);
to keep searchBar
initially "hidden". When user scrolls down searchBar
is dsiplayed
我在 iOS7 上的分组表上searchBar
设置为tableHeaderView
。在viewDidLoad
我必须tableView.contentOffset = CGPointMake(0, 44);
保持searchBar
最初的“隐藏”。当用户向下滚动searchBar
时dsiplayed
Goal:hide searchBar on cancel button tap
目标:点击取消按钮时隐藏搜索栏
In searchBarCancelButtonClicked(searchBar: UISearchBar!)
在 searchBarCancelButtonClicked(searchBar: UISearchBar!)
This did not work:[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
tableView was scrolling too much up, resulting in row 0 going behind toolBar.
这不起作用:[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
tableView 向上滚动太多,导致第 0 行落后于工具栏。
This did not work:tableView.ContentOffset = CGPointMake(0, 44)
- nothing happens
这不起作用:tableView.ContentOffset = CGPointMake(0, 44)
- 没有任何反应
This did not work:tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height)
- nothing happens
这不起作用:tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height)
- 没有任何反应
This did not work:tableView.setContentOffset(CGPointMake(0, 44), animated: true);
Again tableView was scrolling too much up, resulting in row 0 going behind toolBar.
这不起作用:tableView.setContentOffset(CGPointMake(0, 44), animated: true);
tableView 再次向上滚动太多,导致第 0 行落后于工具栏。
This worked partially:tableView.setContentOffset(CGPointMake(0, 0)
but titleForHeaderInSection
was going behind toolBar
这部分有效:tableView.setContentOffset(CGPointMake(0, 0)
但titleForHeaderInSection
落后于工具栏
THIS WORKED:tableView.setContentOffset(CGPointMake(0, -20)
这有效:tableView.setContentOffset(CGPointMake(0, -20)
Seems not logical but only -20 moved it up to correct position
似乎不合逻辑但只有 -20 将其向上移动到正确位置
回答by user3246173
Note that the accepted answer will crash if there is no data in the tableview. And adding it to viewDidLoad may not work under certain circumstances.
请注意,如果 tableview 中没有数据,则接受的答案将崩溃。并将其添加到 viewDidLoad 在某些情况下可能不起作用。
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; // crashes if no rows/data
Therefore, instead add this line of code:
因此,改为添加以下代码行:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[yourTableView setContentOffset:CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)];
}