UIRefreshControl 需要下拉太远

Posted

技术标签:

【中文标题】UIRefreshControl 需要下拉太远【英文标题】:UIRefreshControl needs to be pulled down too far 【发布时间】:2015-03-05 19:44:07 【问题描述】:

我正在尝试在 UICollectionView 上的项目中实现 UIRefreshControl。它按预期工作,但我需要将UICollectionView 拉动大约是refreshControl 旋转时高度的3 倍(一旦用户松开)。我见过其他应用程序,您只需在 refreshControl 旋转时下拉到它的高度。如何更改我需要下拉的金额?

代码:

(void)viewDidLoad 
  [super viewDidLoad];

  [self.collectionView setBackgroundColor:[UIColor clearColor]];
  self.refreshControl = [UIRefreshControl new];
  [self.refreshControl addTarget:self action:@selector(refreshFavorites) forControlEvents:UIControlEventValueChanged];
  [self.collectionView addSubview:self.refreshControl];
  self.collectionView.alwaysBounceVertical = YES;
 

附上图片以帮助形象化我的意思。我的collectionView 有一排(纯红色)。红色和refreshControl 之间的空间只是我拉下以尝试激活refreshControl 的空间。

在这张图片中,我几乎激活了控件,并且已经在屏幕上拉下了相当多的内容。

在这张图片中,我激活了控件,它开始加载(在它跳跃 ~20-30 pix 之后,但它仍然突出了它的重要性)

此图像显示控件在被激活并正在执行动画后处于“静止”状态。

我尝试设置UIRefreshControl 的框架来尝试控制高度,但这不起作用。我还更改了 collectionView:layout:sizeForItemAtIndexPath 的大小,但没有帮助。

【问题讨论】:

你最终解决了这个问题吗?有同样的问题。 【参考方案1】:

如果需要将 UIRefreshControl 拉得太远才能触发,则可能是 ios SDK 的错误。

我建议在视图控制器的帮助下解决这种情况:

- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    // Force update the snapping height of refresh control.
    [self.refreshControl didMoveToSuperview];

另外如果你不介意使用私有API,需要更精准的控制,可以这样写:

- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    @try 
        [self.refreshControl setValue:@(60) forKey:@"_snappingHeight"];
    
    @catch (NSException *exception) 
    

这适用于 iOS 7-10。没有 App Store 审核问题。


往里看

UIRefreshControl 有一个名为 snappingHeight 的属性。此属性控制用户需要下拉的距离。但不幸的是,这个值并不总是正确设置,尤其是你有一个自定义视图层次结构。

UIRefreshControl 有一个私有方法调用_updateSnappingHeight,这个方法也在didMoveToSuperview 中调用。因此手动调用didMoveToSuperview 可以更新错误的捕捉值。

【讨论】:

非常好!谢谢,它拯救了我的一天! 太棒了!我在 iPhone 5s iOS 12.3.1 上遇到问题。希望这个错误能尽快修复。 在 iOS 13+ 上,我可以建议在 DispatchQueue.main.async 中调用它。【参考方案2】:

对于仍在寻找答案的人。到目前为止,我有一个明确且最好的答案......

SWIFT 3:

viewDidLoad() 内部:

self.refresher = UIRefreshControl()
self.refresher.tintColor = UIColor.red
self.scrollView.addSubview(self.refresher)

下一步如果您的 View 是 ViewController - 像这样实现 ScrollViewDelegate:

class YourViewController: UIViewController, UIScrollViewDelegate

一旦你有你的滚动视图@IBOUlet 链接...... 继续在 viewDidLoad() 中将 scrollView 委托设置为 self ,如下所示:

self.scrollView.delegate = self

接下来,既然你已经设置了代表,设置 scrollViewDidScroll 函数并实现它,以检查下拉的人是否像这样通过 -90:

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    if scrollView == self.scrollView
    
        if scrollView.contentOffset.y < -90  && !self.refresher.isRefreshing
            self.refresher.beginRefreshing()
            self.Refresh()
            print("zz refreshing")
        
    

现在,请注意我们没有

self.refresher.addTarget(self, action: #selector(self.Refresh()), for: UIControlEvents.valueChanged)

我们也根本不需要它。相反,我们在调用 beginRefresh() 之后调用实际函数...只要确保在您希望结束的地方调用 endRefresh()

【讨论】:

请注意,滚动视图在滚动(拖动)到原始偏移量时仍会调用beginRefreshing()【参考方案3】:

在我的例子中,我发现 UIviewcontroller 的模拟大小没有问题。

我只是对固定的 UIViewcontroller 的模拟大小进行更改。

这一更改解决了我的问题。

【讨论】:

你结束了我 4 小时的挫败感 :)【参考方案4】:

此处列出的解决方案均不适合我。 我找到的解决方案是在viewDidAppear 中使用refresh.didMoveToSuperview()

完整的解决方案:

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        refresh.didMoveToSuperview()
    

【讨论】:

这实际上是该线程中列出的解决方案之一,您的解决方案已经晚了大约 3 年 :)【参考方案5】:

斯威夫特

基于@BB9z Objective-C 答案:

refreshControl.setValue(100, forKey: "_snappingHeight")

【讨论】:

【参考方案6】:

在 iOS 10.2 中遇到了这个问题所以对于任何仍然受此困扰的人,我找到了一种无需接触私有 API 方法的方法(尽管这也解决了这个问题)。

我发现当设备在 iPad 上旋转时出现问题。 UIRefreshControl 在纵向上表现良好,但在设备旋转时会开始出错。在那之后,无论它处于什么方向,它总是需要被拖得太远而不是需要被激活。

我的解决方案是基于这个答案:Offsetting UIRefreshControl

每当设备旋转并且它工作时,我都尝试设置 UIRefreshControl 的框架。它并不理想,因为它不使用 AutoLayout,但它比使用私有 API 更干净。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];

-(void)didRotate:(NSNotification *)notification 

    [self.refreshControl setFrame:CGRectMake(0, 0, 20, 20)];
    [self.refreshControl setNeedsLayout];


【讨论】:

以上是关于UIRefreshControl 需要下拉太远的主要内容,如果未能解决你的问题,请参考以下文章

IOS6.0自带下拉刷新控件UIRefreshControl

如何自定义 UIRefreshControl 以使下拉高度低于默认值

iOS - Storyboard 使用 UIRefreshControl 下拉刷新

UIRefreshControl 在下拉时崩溃 - 未捕获的异常 Swift

新浪微博客户端(18)-集成下拉刷新控件UIRefreshControl

下拉刷新上拉加载更多