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了所有的线,如下图所示。
该代码行正在工作,因为它应该。
UITableView
的contentOffset
的解释:
例如,如果你有一个高度为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);