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