问题
In viewWillAppear
, I have added UISearchBar
as my headerview of UITableView
. When view loads, I hides UISearchbar
under UINavigationBar
using contentOffSet of UITableView
. When user pull down the tableview the searchbar gets displayed.
After adding headerview I hides it using below code.
self.tableView.contentOffset = CGPointMake(0, 40); //My searhbar height is 40
But at times contentOffSet
is not hiding headerview. What can be the mistake.
回答1:
This worked for me:
// 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));
});
Put it in your -viewDidLoad or -viewWillAppear
回答2:
In earlier versions of the iOS SDK, methods such as viewWillAppear
ran on the main thread, they now run on a background thread which is why the issue now occurs.
Most callbacks tend to fire on a background thread so always check for thread safety when doing UI calls.
Dispatch the change to the content offset on the main thread:
Objective 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)
}
回答3:
Not sure what the reason is (don't have time to research it right now), but I solved this issue by using performSelector
after a delay of 0. Example:
- (void)viewWillAppear:(BOOL)animated {
...
[self performSelector:@selector(hideSearchBar) withObject:nil afterDelay:0.0f];
}
- (void)hideSearchBar {
self.tableView.contentOffset = CGPointMake(0, 44);
}
回答4:
This worked for me.
self.tableView.beginUpdates()
self.tableView.setContentOffset( CGPoint(x: 0.0, y: 0.0), animated: false)
self.tableView.endUpdates()
Objective-C :
[_tableView beginUpdates];
[_tableView setContentOffset:CGPointMake(0, 0)];
[_tableView endUpdates];
回答5:
I fixed it with layoutIfNeeded()
self.articlesCollectionView.reloadData()
self.articlesCollectionView.layoutIfNeeded()
self.articlesCollectionView.setContentOffset(CGPoint(x: 0, y: 40), animated: false)
回答6:
It may be because of the "Adjust Scroll View Insets" attribute on the View Controller. See this: https://stackoverflow.com/a/22022366
EDIT: Be sure to check the value of 'contentInset' to see what's happening, since this also has an effect on the scroll view. This value is changed after viewWillAppear: when "Adjust Scroll View Insets" is set, which seems to be what others are trying to avoid by using dispatch queues and the like.
回答7:
After one hour of tests the only way that works 100% is this one:
-(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];
}
with this approach you can always hide the search bar if is empty
回答8:
In my case the problem was that I called
[_myGreatTableView reloadData];
before getting the _tableView.contentOffset.y
. This always returned '0'.
So I switched the order of these methods and now it works.
This is quite a strange behavior in my opinion, because offset returned 0 but the UI still kept the scroll position of the table.
回答9:
The problem is auto masking. Select your table and make sure you have selected all the lines, as in the image below.
回答10:
The line of code is working as it should.
Explaination of contentOffset
of a UITableView
:
For example, if you have a table view of height 100. Its content may be more than it's view, say 150. contentOffset
will tell the table from where in the content to start from. Say contentOffset = (0, 40)
, the content will be shown after 40 of it's height.
Note: Once the content is scrolled, there is no affect of the previously set contentOffset
.
回答11:
You need to hide the search bar by yourself when you scroll the table. So don't put it as a UITableView
header. You could hide it by setting its height to zero. That way if your table view is set to auto resize, it will expand.
回答12:
The problem may be with the search bar size. Try the following line of code.
[searchBar sizeToFit];
回答13:
If your table will always have at least one row, just scroll to the first row of the table and the search bar will be hidden automatically.
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
If you put the above code on viewDidLoad, it will throw an error because the tableView hasn't loaded yet, so you have to put it in viewDidAppear because by this point the tableView has already loaded.
If you put it on viewDidAppear, everytime you open the tableView it will scroll to the top.
Maybe you don't want this behaviour if the tableView remains open, like when it is a UITabBar View Controller or when you do a segue and then come back. If you just want it to scroll to the top on the initial load, you can create a variable to check if it is an initial load so that it scrolls to the top just once.
First define a variable called isInitialLoad in the view controller class and set it to "true":
var isInitialLoad = true
And then check if isInitialLoad is true on viewDidAppear and if it is true, scroll to the top and set the isInitialLoad variable to false:
if isInitialLoad {
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
isInitialLoad = false
}
回答14:
In iOS 7/8/9 simple self.automaticallyAdjustsScrollViewInsets = NO; solved the problem in my case
回答15:
self.tableView.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height -80, 0, 0, 0);
来源:https://stackoverflow.com/questions/15222186/uitableview-contentoffset-is-not-working-properly