UITableView contentOffSet无法正常工作

时间:2013-03-05 11:05:57

标签: iphone ios uitableview contentoffset

viewWillAppear中,我添加了UISearchBar作为UITableView的标题视图。加载视图时,我使用UISearchbar的contentOffSet隐藏UINavigationBar下的UITableView。当用户下拉tableview时,会显示搜索栏。

添加标题视图后,我使用下面的代码隐藏它。

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

但有时contentOffSet并未隐藏标题视图。可能是什么错误。

15 个答案:

答案 0 :(得分:30)

这对我有用:

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

答案 1 :(得分:19)

不确定原因是什么(没有时间立即研究),但我在延迟0后使用performSelector解决了这个问题。例如:

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

- (void)hideSearchBar {
    self.tableView.contentOffset = CGPointMake(0, 44);
}

答案 2 :(得分:18)

在早期版本的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];
});

Swift 3

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

答案 3 :(得分:4)

这对我有用。

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];

答案 4 :(得分:2)

可能是因为View Controller上的“调整滚动视图插入”属性。 请参阅:https://stackoverflow.com/a/22022366

编辑: 请务必检查'contentInset'的值以查看发生了什么,因为这也会影响滚动视图。 在viewWillAppear之后更改此值:当设置“调整滚动视图插入”时,这似乎是其他人试图通过使用调度队列等来避免的。

答案 5 :(得分: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];
}

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

答案 6 :(得分:2)

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

 [_myGreatTableView reloadData];

获取_tableView.contentOffset.y之前。这总是返回'0'。

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

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

答案 7 :(得分:1)

我通过 layoutIfNeeded()

修复了该问题
Item

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

enter image description here

答案 10 :(得分:0)

问题可能出在搜索栏大小上。请尝试以下代码行。

[searchBar sizeToFit];

答案 11 :(得分:0)

代码行正常工作。

解释contentOffset的{​​{1}}:

例如,如果你有一个高度为100的表视图。它的内容可能超过它的视图,比如说150. UITableView将告诉表格内容的起始位置。说contentOffset,内容将在40的高度后显示。

注意:滚动内容后,不会影响之前设置的contentOffset = (0, 40)

答案 12 :(得分:0)

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

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

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

如果您将上述代码放在 viewDidLoad 上,则会抛出错误,因为尚未加载tableView,因此您必须将其放在 viewDidAppear 中,因为这一点tableView已经加载了。

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

如果tableView保持打开状态,也许你不想要这种行为,就像它是一个UITabBar View Controller,或者当你做一个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
}

答案 13 :(得分:0)

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

答案 14 :(得分:-3)

self.tableView.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height -80, 0, 0, 0);