24

在中,我viewWillAppear已将. 当视图加载时,我隐藏在使用 contentOffSet 的. 当用户拉下 tableview 时,会显示搜索栏。UISearchBarUITableViewUISearchbarUINavigationBarUITableView

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

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

但有时contentOffSet并没有隐藏headerview。可能是什么错误。

4

15 回答 15

37

这对我有用:

// 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 中

于 2014-04-25T22:40:14.473 回答
19

不知道是什么原因(现在没时间研究),但我performSelector在延迟为 0 后使用解决了这个问题。示例:

- (void)viewWillAppear:(BOOL)animated {
    ...
    [self performSelector:@selector(hideSearchBar) withObject:nil afterDelay:0.0f];
}

- (void)hideSearchBar {
    self.tableView.contentOffset = CGPointMake(0, 44);
}
于 2013-07-15T15:36:17.657 回答
19

在早期版本的 iOS SDK 中,诸如viewWillAppear在主线程上运行的方法现在在后台线程上运行,这就是现在出现问题的原因。

大多数回调倾向于在后台线程上触发,因此在进行 UI 调用时始终检查线程安全。

将更改分发到主线程上的内容偏移量:

目标 C

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

斯威夫特 3

DispatchQueue.main.async {
            let offset = CGPoint.init(x: 0, y: self.searchBar.bounds.height)
            self.tableView.setContentOffset(offset, animated: false)
        }
于 2016-10-17T01:44:32.553 回答
5

这对我有用。

self.tableView.beginUpdates()
self.tableView.setContentOffset( CGPoint(x: 0.0, y: 0.0), animated: false)
self.tableView.endUpdates()

目标-C:

[_tableView beginUpdates];
[_tableView setContentOffset:CGPointMake(0, 0)];
[_tableView endUpdates];
于 2017-06-29T09:23:39.033 回答
4

我用layoutIfNeeded()修复了它

    self.articlesCollectionView.reloadData()
    self.articlesCollectionView.layoutIfNeeded()
    self.articlesCollectionView.setContentOffset(CGPoint(x: 0, y: 40), animated: false)
于 2018-08-22T16:13:29.837 回答
2

经过一小时的测试后,唯一可以 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];
}

使用这种方法,如果为空,您始终可以隐藏搜索栏

于 2015-04-10T10:36:50.387 回答
2

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

编辑:一定要检查'contentInset'的值,看看发生了什么,因为这也会影响滚动视图。此值在 viewWillAppear: 设置后更改,这似乎是其他人试图通过使用调度队列等来避免的。

于 2014-10-17T23:01:01.970 回答
2

就我而言,问题是我打电话给

 [_myGreatTableView reloadData];

在得到_tableView.contentOffset.y. 这总是返回“0”。

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

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

于 2016-07-12T07:03:17.643 回答
0

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

[searchBar sizeToFit];
于 2013-03-06T08:58:42.427 回答
0

滚动表格时需要自己隐藏搜索栏。所以不要把它作为UITableView标题。您可以通过将其高度设置为零来隐藏它。这样,如果您的表格视图设置为自动调整大小,它将展开。

于 2013-03-05T11:18:04.100 回答
0

问题是自动屏蔽。选择您的表格并确保您已选择所有行,如下图所示。

在此处输入图像描述

于 2013-03-05T12:30:24.647 回答
0

这行代码正在正常工作。

acontentOffset的解释UITableView

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

注意:一旦内容滚动,就没有之前设置的影响contentOffset

于 2014-06-25T08:18:25.387 回答
0

在 iOS 7/8/9 中简单的 self.automaticallyAdjustsScrollViewInsets = NO; 解决了我的问题

于 2017-05-30T10:25:54.827 回答
0

如果您的表格总是至少有一行,只需滚动到表格的第一行,搜索栏就会自动隐藏。

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

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

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

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

如果 tableView 保持打开状态,例如当它是 UITabBar 视图控制器或执行 segue 然后返回时,您可能不希望出现这种行为。如果您只想让它在初始加载时滚动到顶部,您可以创建一个变量来检查它是否是初始加载,以便它只滚动到顶部一次。

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

var isInitialLoad = true

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

if isInitialLoad {
    let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
    self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
    isInitialLoad = false
}
于 2015-12-16T21:22:00.367 回答
-3
self.tableView.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height -80, 0, 0, 0);
于 2015-05-12T18:43:17.510 回答