iOS7的UIRefreshControl更改了contentInset。

12

我的应用中有一个UINavigationControllerUINavigationBar设置为不透明以及所有的滚动视图都不在导航栏下方。

在一个视图中,我有一个UITableView。在我的 iPhone 5 上,UITableView的框架是(0 0; 320 504)。即高度为568-64(导航栏和状态栏的高度)。

UITableViewcontentInset(0, 0, 0, 0)。当表格视图首次加载时,contentOffset(0, 0)

这很好。运作得非常出色。

我向表格视图添加了一个UIRefreshControl。这个功能可以使用几次,但之后进行几次下拉刷新后,顶部的内容就会“卡”在导航栏下面。

当发生这种情况时,我检查contentInset,它现在变成了(-60, 0, 0, 0)

有没有办法阻止UIRefreshControl更改contentInset


我删除了我的答案,因为你显然已经排除了它。你正在调用endRefreshing吗? - jhilgert00
没问题。是的,当我在控件上调用endRefreshing时,它会消失。这个方法可以正常工作几次,但之后就会出现问题,contentInset会改变并将顶部几行隐藏在导航栏下面。 - Fogmeister
你可能可以在刷新后重置你的框架,但你不应该这样做。 - jhilgert00
我现在通过手动将contentInset设置回0来解决了这个问题,但现在它不会动画消失刷新控件,而是直接跳回去。如果我尝试动画它,它就会崩溃。哈哈 - Fogmeister
你可以尝试的最后一件事是在IB中添加UIRefreshControl。如果在Storyboard中单击UITableviewController,并在属性检查器中将Refreshing设置为启用,它会为您添加一个UIRefresh控件。然后,您可以将IBAction链接到它或在viewDidLoad中添加选择器。这可能值得一试。 - jhilgert00
啊,听起来你可能有点眉目了。不过很遗憾,我正在使用一个带有UITableView的UIViewController而不是UITableViewController。下次我一定会试试看。谢谢。 - Fogmeister
4个回答

7

这可能是为什么UIRefreshControl目前只支持UITableViewController而不是添加到任何滚动视图(在许多情况下,您可以摆脱它)的原因。

刷新控件通过调整滚动视图的内容插图来完成其工作 - 特别是当它结束刷新时。不幸的是,视图控制器也在调整滚动视图的内容插图以适应半透明的导航栏和状态栏。这会带来一些问题。这在iOS 6上也是一个问题吗(或者像我处理同样的问题时所说的“好老的iOS 6”)。

最快的解决方案可能是将表视图作为子UITableViewController而不是简单的子视图添加。我认为UITableViewController在刷新结束时会自动管理插图。如果这行不通,我有解决方法,但需要等到我回到办公室才能提供。


1
我似乎已经解决了这个问题。我意识到NSOperationcompletionBlock在同一个线程上调用操作。这就是我调用endRefreshing的地方。我将其分派到主线程,现在它可以正常工作,而不需要更改contentInset。你有关于UIRefreshControl只官方支持UITVC的链接吗? - Fogmeister
文档中说它是为分配给UITVC而制作的。addSubview: 这个东西只在SO上提到过,文档中从未提到过。 - jrturton
请查看Dave DeLong在此答案中的评论:https://dev59.com/A2cs5IYBdhLWcg3w5H9a#12502450 - jrturton
我将整个东西改成了uitvc,现在一切都正常工作了。即使改为主线程后,我仍然遇到了显示奇怪行为的问题。 - Fogmeister
我遇到了完全相同的问题。我正在使用带有UICollectionView的UiRefreshControl。它似乎改变了我的contentInset。在结束刷新后,我再次将我的contentInset设置为正确的值。这样可以吗?还是我们必须避免在CollectionView中使用UIRefreshControl? - user1010819

7

如果有人在更改控件属性(如属性标题、色调等)时遇到UIRefreshControl的问题,我会在这里添加答案:

不要在-viewDidLoad:中操纵UIRefreshControl,而应该使用-viewDidAppear:


1
确保在每次页面出现时,都要添加refreshcontrol,如果(!refreshControl) else放置一个条件。 - George

5

重置您的表视图contentInset。

-(void)pullToRefresh
{
    [self.tableView reloadData];
    [self.refreshControl endRefreshing];
    [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
}

4
你需要在你的UICollectionView中重写setContentInset:方法。
- (void)setContentInset:(UIEdgeInsets)contentInset {
  if (self.tracking) {
    CGFloat difference = contentInset.top - self.contentInset.top;
    CGPoint translation = [self.panGestureRecognizer translationInView:self];
    translation.y -= difference * 3.0 / 2.0;
    [self.panGestureRecognizer setTranslation:translation inView:self];
  }
  [super setContentInset:contentInset];
}

您提到的网址已不存在。 - Nagarjun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接