UITableView contentOffSet工作不正常

viewWillAppear ,我添加了UISearchBar作为UITableView headerview。 加载视图时,我使用UITableView contentOffSet隐藏UINavigationBar下的UISearchbar 。 当用户拉下桌面时,search栏会显示。

添加headerview后,我使用下面的代码隐藏它。

 self.tableView.contentOffset = CGPointMake(0, 40); //My searhbar height is 40 

但有时contentOffSet不隐藏headerview。 什么可能是错误的。

这对我工作:

 // contentOffset will not change before the main runloop ends without queueing it, for iPad that is dispatch_async(dispatch_get_main_queue(), ^{ // The search bar is hidden when the view becomes visible the first time self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.searchBar.bounds)); }); 

把它放在你的-viewDidLoad或-viewWillAppear中

不知道是什么原因(现在没有时间研究它),但是我通过在延迟0之后使用performSelector来解决这个问题。例如:

 - (void)viewWillAppear:(BOOL)animated { ... [self performSelector:@selector(hideSearchBar) withObject:nil afterDelay:0.0f]; } - (void)hideSearchBar { self.tableView.contentOffset = CGPointMake(0, 44); } 

调度主线程上内容偏移量的变化:

目标C

 dispatch_async(dispatch_get_main_queue(), ^{ CGPoint offset = CGPointMake(0, self.searchBar.bounds.height) [self.tableView setContentOffset:offset animated:NO]; }); 

Swift 3

 DispatchQueue.main.async { let offset = CGPoint.init(x: 0, y: self.searchBar.bounds.height) self.tableView.setContentOffset(offset, animated: false) } 

这可能是因为View Controller上的“Adjust Scroll View Insets”属性。 看到这个: https : //stackoverflow.com/a/22022366

编辑:一定要检查'contentInset'的值来看看发生了什么,因为这也对滚动视图有影响。 这个值在viewWillAppear之后被改变:设置了“Adjust Scroll View Insets”时,这似乎是其他人试图通过使用调度队列等来避免的。

经过一个小时的testing,100%的工作是这样的:

 -(void)hideSearchBar { if([self.tableSearchBar.text length]<=0 && !self.tableSearchBar.isFirstResponder) { self.tableView.contentOffset = CGPointMake(0, self.tableSearchBar.bounds.size.height); self.edgesForExtendedLayout = UIRectEdgeBottom; } } -(void)viewDidLayoutSubviews { [self hideSearchBar]; } 

使用这种方法,您可以随时隐藏search栏,如果是空的

在我的情况下,问题是我打电话

  [_myGreatTableView reloadData]; 

在获取_tableView.contentOffset.y之前。 这总是返回“0”。

所以我切换了这些方法的顺序,现在它工作。

在我看来这是一个很奇怪的行为,因为偏移返回0,但UI仍然保持表的滚动位置。

问题是自动屏蔽。 select你的桌子,并确保你已经select了所有的线,如下图所示。

在这里输入图像说明

该代码行正在工作,因为它应该。

UITableViewcontentOffset的解释:

例如,如果你有一个高度为100的表格视图,它的内容可能比它的视图更多,比如150. contentOffset会告诉表格从内容的哪个位置开始。 说contentOffset = (0, 40) ,内容会显示在40的高度之后。

注意:滚动内容后,不会影响以前设置的contentOffset

滚动表格时,您需要自己隐藏search栏。 所以不要把它作为一个UITableView头。 您可以通过将其高度设置为零来隐藏它。 这样,如果您的表格视图设置为自动resize,它将展开。

问题可能与search栏的大小有关。 尝试下面的代码行。

 [searchBar sizeToFit]; 

如果您的表格总是至less有一行,请滚动到表格的第一行,search栏将自动隐藏。

 let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0) 

self.tableView.selectRowAtIndexPath(firstIndexPath,animated:false,scrollPosition:.Top)

如果你把上面的代码放在viewDidLoad中 ,它会抛出一个错误,因为tableView还没有加载,所以你必须把它放在viewDidAppear中,因为这个时候tableView已经加载了。

如果你把它放在viewDidAppear上 ,每次打开tableView就会滚动到顶部。

也许你不希望这种行为,如果tableView保持打开,就像它是一个UITabBar视图控制器或当你做一个继续,然后回来。 如果您只是想在初始加载时滚动到顶部,您可以创build一个variables来检查它是否是初始加载,以便它只滚动一次。

首先在视图控制器类中定义一个名为isInitialLoad的variables,并将其设置为“true”:

 var isInitialLoad = true 

然后检查viewDidAppear上的isInitialLoad是否为true,如果为true,则滚动到顶部并将isInitialLoadvariables设置为false:

 if isInitialLoad { let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0) self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top) isInitialLoad = false } 

在iOS 7/8/9简单的self.automaticallyAdjustsScrollViewInsets = NO; 在我的情况下解决了这个问题

这对我有效。

 self.tableView.beginUpdates() self.tableView.setContentOffset( CGPoint(x: 0.0, y: 0.0), animated: false) self.tableView.endUpdates() 
 self.tableView.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height -80, 0, 0, 0);