iPhone:默认隐藏UITableView搜索栏
我使用Interface Builder创建了一个表格视图,我添加了库的搜索栏和搜索显示控制器来添加搜索功能。但是,IB将其设置为在视图第一次显示时可以在屏幕顶部显示条。iPhone:默认隐藏UITableView搜索栏
我想知道如何让默认情况下隐藏搜索栏,但仍然可以使用表格视图进行滚动(例如,请参阅Apple's Mail应用程序)。我试过在viewDidLoad
中调用scrollRectToVisible:animated:
来向下滚动表格视图,但无济于事。默认情况下隐藏搜索栏的首选方式是什么?
首先确保将UISearchBar添加到UITableView的tableHeaderView,以便它与表的内容一起滚动并且不固定到视图的顶部。
搜索栏不计为在tableview中的行,因此,如果滚动的tableview的顶部的第一行中,“隐藏”了搜索栏:
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
或夫特:
yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
确保不滚动tableview中包含的数据之前(scrollToRowAtIndexPath
将引发异常,如果给定indexPath没有指向一个有效行(即如果实现代码如下为空))。
我发现当Notes视图空白时,“Notes”应用程序无法搜索项目。所以我认为这只是使用-(void)addSubview:(UIView *)view
开始添加一个空白表。当你添加一个项目到它的数据源数组时,它会运行另一个代码来加载tableView。
所以我的解决办法是:
if([self.arrayList count] > 0)
{
[self.tableView reloadData]; //use jdandrea's code to scroll view when cell==nil in cellForRowAtIndexPath
self.tableView.scrollEnabled = YES;
}
else
{
tableBlank = [[UITableView alloc]initWithFrame:CGRectMake(0,0,320,416) style:UITableViewStylePlain] autorelease];
tableBlank.delegate = self;
tableBlank.dataSource = self;
[self.view addSubview:tableBlank];
}
希望这有助于:-)
的contentOffset由蒂姆和Joe D'安德烈的评论所指出的,但是这是一个有点通过添加扩展动画来隐藏搜索栏。我注意到搜索栏刚刚消失有点意外。
对于那些谁想要的目标的iOS 4.0及以上的小更新,试试这个:
[UIView animateWithDuration:0.4 animations:^{
self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
} completion:nil];
以前的答案:
[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];
不要”添加的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;
}
如果您不想在默认情况下看到它:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView setContentOffset:CGPointMake(0, 44)];
}
我也得到了取消按钮隐藏它再次....(和取下键盘)
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
[self.searchBar resignFirstResponder];
}
更改的tableView的界限,这可以在里面viewDidLoad
做,再加上你不必担心,如果表是空的或不是(避免除外)。
CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
一旦用户向下滚动搜索栏将出现并表现表正常
有很多的答案,这样的解决方案,但是,没有工作对我非常好。
这个效果很好。没有动画,并在-viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.contentOffset = CGPointMake(0, self.searchBar.frame.size.height - self.tableView.contentOffset.y);
}
做
注:
代码假定你有searchBar
@property
链接到搜索栏。 如果不是,您可以使用self.searchDisplayController.searchBar
而不是
请注意,如果tableview中没有数据,则接受的答案将会崩溃。并且在某些情况下将其添加到viewDidLoad可能不起作用。
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; // crashes if no rows/data
因此,而不是添加这行代码:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[yourTableView setContentOffset:CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)];
}
以上都不为我工作,所以为了以防万一,如果有人将有同样的问题。我有searchBar
设置为tableHeaderView
在iOS7上的分组表格。在viewDidLoad
我有tableView.contentOffset = CGPointMake(0, 44);
保持searchBar
最初“隐藏”。当用户向下滚动searchBar
是dsiplayed
目标:隐藏取消按钮自来水
搜索栏在searchBarCancelButtonClicked(searchBar: UISearchBar!)
这不起作用:[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
的tableView被滚动太多了,导致零行在toolBar后面。
这不起作用:tableView.ContentOffset = CGPointMake(0, 44)
- 什么也没有发生
这不起作用:tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height)
- 什么也没有发生
这不起作用:tableView.setContentOffset(CGPointMake(0, 44), animated: true);
同样的tableView被滚动太多了,导致行0落后于toolBar。
这部分工作:tableView.setContentOffset(CGPointMake(0, 0)
但titleForHeaderInSection
要去背后工具栏
这工作:tableView.setContentOffset(CGPointMake(0, -20)
似乎不符合逻辑的,但只有-20移动它到正确的位置
老实说,没有任何答案真的解决了这个问题(对我来说)。如果你的表视图没有行或行高不同,这些答案是不够的。加入的故事板平原TableView中的风格tableHeaderView
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tableView.contentOffset = (CGPoint){.y = self.tableView.contentOffset.y + self.searchController.searchBar.frame.size.height};
}
我的目标是隐藏搜索栏时,视图控制器被加载并显示栏时,在顶部用户向下滚动:
唯一可行的事的UITableView。 所以,我使用斯威夫特并增加了扩展:
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)
}
}
}
}
在viewDidLoad中()只要致电:
self.tableView.hideSearchBar()
其他回答这个问题无论是在没有工作所有对我来说,在tableView有0行时都有奇怪的行为,或者在父项和嵌套行项目之间来回滚动时滚动位置。这个工作对我(的目标是隐藏在负载时的UISearchBar):
public override func viewWillAppear(animated: Bool) {
if self.tableView.contentOffset.y == 0 {
self.tableView.contentOffset = CGPoint(x: 0.0, y: self.searchBar.frame.size.height)
}
}
说明
任何时候tableView
会出现,这个代码检查,看是否的UISearchBar是可见的(指y
位置的contentOffset
,也就是滚动位置,是0
)。如果是,它只是向下滚动searchBar的高度。如果searchBar不可见(请考虑tableView
中的项目的较大列表),那么它不会尝试滚动tableView
,因为当您从嵌套的订单项返回时,这会弄乱定位。
旁注
我建议把这个代码在一个单独的方法来确保单一职责,并给您的可重用性在代码中随时调用它。
当iOS8没有足够的行填充tableView时,所有现有的解决方案都不适用于我,因为iOS会在这种情况下自动调整插入。 (当有足够的行时现有的答案是好的)
在这个问题上浪费了6小时后,我终于得到了这个解决方案。
总之,如果没有足够的单元格,您需要将空单元格插入到tableView中,因此tableView的内容大小足够大,iOS不会为您调整嵌入。
下面是我在Swift中做的:
1。)声明变量minimumCellNum
作为一类属性
var minimumCellNum: Int?
2.)计算minimumCellNum
和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.)在tableView(tableView: UITableView, numberOfRowsInSection section: Int))
let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
return numOfYourRows
} else {
return minimumCellNum!
}
4.设置tableView.contentOffset
)注册一个空格,其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
}
在tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if tableView == self.tableView {
if numOfYourRows < (indexPath.row + 1) {
return
}
YOUR LOGIC OF SELECTING A CELL
}
这不是一个完美的解决方案,但它是唯一的解决方法是真的对我的作品在iOS 8.我想知道如果有5)一个整洁的解决方案。
如果您的表格总是至少有一行,只需滚动到表格的第一行,搜索栏就会自动隐藏起来。
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(firstIndexPath,动画:假的,则scrollPosition:.TOP)
如果你把上面的代码上viewDidLoad中,它会抛出一个错误,因为的tableView还没有装载尚未,所以你必须把它放在viewDidAppear因为这一点tableView已经加载。
如果你把它放在viewDidAppear,每次你打开tableView它会滚动到顶部。
也许你不希望这种行为,如果tableView保持打开,就像它是一个UITabBar视图控制器或当你做一个继续,然后回来。如果您只是希望它在初始加载时滚动到顶部,您可以创建一个变量来检查它是否是初始加载,以便它只滚动一次。
第一定义一个称为isInitialLoad变量在视图控制器类和它设置为等于“真”:
var isInitialLoad = true
然后检查isInitialLoad是viewDidAppear真,并且如果它是真实的,滚动到顶部并将isInitialLoad变量设置为false:
if isInitialLoad {
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
isInitialLoad = false
}
不要忘记带状态栏和导航栏考虑。我的表视图控制器嵌入导航控制器,在viewDidAppear
:
tableView.contentOffset = CGPointMake(0, -20) // -20 = 44 (search bar height) - 20 (status bar height) - 44 (navigation bar height)
为我工作。
对于斯威夫特:
只是要实现代码如下内容y偏移,这应该是像搜索栏的高度。
self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height)
对于斯威夫特3+
我这样做:
声明这个var
:
var searchController = UISearchController()
而在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)
斯威夫特3
也适用于空表!
在我的环境中,我通过xib文件加载自定义单元格,rowHeight是自动设置的。
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.tableView.contentOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y + self.searchController.searchBar.bounds.height)
}
下面的代码为我工作
self.tableView.contentOffset = CGPointMake(0.0, 44.0);
我尝试设置内容偏移和scrollToIndexpath但没有满意的工作。我删除tableHeaderView的设置从viewDidLoad中搜索栏,并设置滚动型代表如下
override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 && tableView.tableHeaderView == nil {
tableView.tableHeaderView = searchController.searchBar
tableView.setContentOffset(CGPointMake(0, scrollView.contentOffset.y + searchController.searchBar.frame.size.height), animated: false)
}
}
这工作就像一个charm.The内容偏移设置为平滑滚动目的
我有类似的问题。唯一的办法,我发现解决这个问题是在UITableView contentOffset属性上使用键值观察者。
经过一些调试,我发现问题出现只是如果表视图的内容大小比tableview小。我在viewWillAppear时开始KVO。 并且出现查看后0.3秒的发送停止KVO。每当contentOffset变为0.0时,KVO会在搜索栏高度上反应并设置contentOffset。 我在0.3秒后停止KVO异步,因为即使在视图出现之后,视图布局也会重置contentOffset。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
-(void)viewDidAppear:(BOOL)animated{
__weak typeof (self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.tableView removeObserver:self forKeyPath:@"contentOffset"];});
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"contentOffset"] && self.tableView.contentOffset.y == 0.0) {
self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.tableView.tableHeaderView.frame));
}
}
-(void)dealloc {
[self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}
此作品 - 谢谢! – Tim 2009-07-06 23:45:33
其实,我得到的问题是,如果没有足够的行来填充屏幕,表格视图将不会滚动 - 在一行或两行表格中,此代码不会执行任何操作。那是预期的行为?我能以某种方式避开它吗? – Tim 2009-07-10 19:54:22
这样的声音通常是有意的(如果适合屏幕显示所有内容)。然而邮件应用程序似乎可以滚动搜索栏,即使没有行存在。不幸的是,我无法在我自己的代码中重现这一点。 – Zargony 2009-07-14 21:51:21