UIRefreshControl需要被拉得太远

时间:2015-03-05 19:44:08

标签: ios

我正在尝试在UIRefreshControl的项目中实施UICollectionView。它按预期工作,但我需要将UICollectionView拉动refreshControl的高度约为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有一行(纯红色)。红色和UIRefreshControl之间的空格只是我拉下来试图激活collectionView:layout:sizeForItemAtIndexPath的空间。

在这张图片中,我几乎已经激活了控件,我已经在屏幕上拉了相当数量。

enter image description here

在这张图片中,我已经激活了控件并且它开始加载(在它跳跃~20-30像素之后,但它仍然突出显示这是多么重要)

enter image description here

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

enter image description here

我已尝试设置{{1}}的框架以尝试控制高度,但这不起作用。我也改变了{{1}}中没有帮助的大小。

6 个答案:

答案 0 :(得分:17)

如果需要将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调用可以更新错误的捕捉值。

答案 1 :(得分:2)

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

SWIFT 3:

在viewDidLoad()中:

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

Next如果你的View是一个ViewController - 像这样实现ScrollViewDelegate:

class YourViewController: UIViewController, UIScrollViewDelegate

将scrollView @IBOulet链接起来后...... 继续并在viewDidLoad()中将scrollView委托设置为self,如下所示:

self.scrollView.delegate = self

接下来,既然您已设置了委托,请设置scrollViewDidScroll函数并实现它,以检查该人是否通过-90传递-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()

答案 2 :(得分:0)

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

}

答案 3 :(得分:0)

这里列出的所有解决方案都不适合我。 我发现的解决方案是在refresh.didMoveToSuperview()中使用viewDidAppear

完整的解决方案:

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

答案 4 :(得分:0)

就我而言,我发现UIviewcontroller的模拟尺寸没有问题。

我只是更改了固定的UIViewcontroller的模拟大小。

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

答案 5 :(得分:0)

迅速

基于@ BB9z Objective-C答案:

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