切换UITabBarController中的选项卡后,UIRefreshControl卡住了
我有一个UITableViewController作为UINavigationController中的根视图控制器,它依次是UITabBarController中的视图控制器之一。 所有连接在Storyboard中。
我已经在Storyboard中为我的表configuration了UIRefreshControl,通常看起来应该是在拉时:
但是,如果我在其他选项卡之间切换一次或两次,则如下所示:
它不是旋转或任何东西,只是卡住“完整”,并保持这种方式,直到我完全拉动和刷新。
任何想法或build议感激。
user2009606几乎是正确的,我通过调用来修复它
[refreshControl endRefreshing];
上
viewWillAppear:
在切换标签后,refreshControl现在可以正常工作,与状态无关。
我知道这是非常晚,但我从来没有比从未好过。
不幸的是,没有给出的答案为我工作。 唯一可行的是viewWillAppear中这段糟糕的代码:
self.refreshControl = nil; UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refreshFunction) forControlEvents:UIControlEventValueChanged]; self.refreshControl = refreshControl;
每当视图出现时,基本上我都会重新创buildUIRefreshControl。 它的工作,尽pipe同时给出以下警告:
试图改变刷新控制,而不是空闲的强烈不鼓励,可能无法正常工作。
我真的很惊讶,这仍然是一个问题(现在仍然在iOS 9中看到这一点)。 希望这可能对其他人有所帮助。
以下解决scheme可能会帮助你。
CGFloat yTableViewOffset; - (void)viewDidLoad { yTableViewOffset = kNilOptions; } - (void)viewWillAppear:(BOOL)animated { if(yTableViewOffset != kNilOptions) { CGPoint offset = CGPointMake(tableView.contentOffset.x, yTableViewOffset); [refreshControl beginRefreshing]; tableView.contentOffset = offset; } } - (void)viewWillDisappear:(BOOL)animated { if(refreshControl.isRefreshing) { yTableViewOffset = tableView.contentOffset.y; [refreshControl endRefreshing]; } }
总结并提供一个完整的解决scheme。
问题:
如果UIRefreshControl在屏幕过渡期间进行animation处理,它将保持可见状态,但不会进行animation处理。 videohttps://vid.me/Bkb7
另外,如果拉动刷新animation开始但未完成,然后进行转换,则UIRefreshControl将被隐藏但卡住。 videohttps://vid.me/Bkb7
解:
在viewWillAppear上启动UIRefreshControlanimation并在viewDidDisappear上结束。 保存刷新过程的状态以知道何时显示UIRefreshControl。
贝娄是整个解决scheme,也处理适当的animation和简单的拉动刷新animation。
添加到UITableView或子类
初始化:
/// Refresh indicator var refreshControl = UIRefreshControl() /// Refresh state var isRefreshing = false /// Refresh controll update funcion. Set to enable pull to refresh var refreshControllUpdateFunction: (() -> ())? /// Prepeares UIRefreshControll. Call from init func initRefreshControl(){ addSubview(refreshControl) refreshControl.addTarget(self, action: "refreshControllTarget", forControlEvents: .ValueChanged) refreshControl.beginRefreshing() isRefreshing = true }
Superview事件处理程序:
/// Call on viewWillApper func superviewWillApper(){ if isRefreshing && !refreshControl.refreshing{ startRefreshAnimation() } } /// Call on viewDidDisapper func superviewDidDisappear(){ endRefreshAnimation(false, dataFetched: !isRefreshing) }
UIRefreshControlanimation处理程序:
/// Presents animating UIRefreshControll func startRefreshAnimation(){ refreshControl.beginRefreshing() contentOffset = CGPointMake(0, -refreshControl.bounds.size.height) isRefreshing = true } /// Hides UIRefreshControll and saves state of refresh func endRefreshAnimation(wasEmpty: Bool, dataFetched: Bool){ refreshControl.endRefreshing() isRefreshing = !dataFetched if !wasEmpty{ setContentOffset(CGPointZero, animated: true) }else{ setContentOffset(CGPointZero, animated: false) } }
加
table.isRefreshing = true
开始刷新电话。
结果videohttps://vid.me/LyuI
只需在viewWillDisappear:
调用endRefreshing
viewWillDisappear:
为我解决所有问题。
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.refreshControl endRefreshing]; }
在viewWillAppear:
做同样的事情viewWillAppear:
当拉动表格时导致刷新控制奇怪地旋转。
我刚刚看到同样的事情。 我最终做的是viewWillDisappear endRefreshing至less消除了这个问题。 但是,回到选项卡,我期望它重新开始旋转,因为我重新启动刷新过程,并再次调用beginRefreshing,但它不。 当我向下钻取导航然后回来的时候,它确实如此。
我有一个collectionView,我确实设置了它的contentInset。
当推一些ViewControllers,然后按主页button,回去和回弹,UIRefreshControl总是在最上面。
最后我用这个代码暂时避免它。 (丑,但总是显示在上面)
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.refreshControl endRefreshing]; CGPoint currentContentOffset = self.collectionView.contentOffset; [self.collectionView setContentOffset:CGPointMake(currentContentOffset.x, currentContentOffset.y - 1.0f) animated:YES]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; CGPoint currentContentOffset = self.collectionView.contentOffset; [self.collectionView setContentOffset:CGPointMake(currentContentOffset.x, currentContentOffset.y + 1.0f) animated:YES]; }
我想要一些点,像阿尔伯特解决scheme,但不是他的风格。
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; _table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y + 1.0f); } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; _table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y - 1.0f); }
希望我能最终帮助解决这个问题:
使用UITableView和Pull-To-Refresh控件存在一个问题。 这可以很容易解决,通过添加一个UITableViewController。
UITableViewController *tableController = [[UITableViewController alloc] init]; tableController.automaticallyAdjustsScrollViewInsets = NO; [tableController willMoveToParentViewController:self]; [self addChildViewController:tableController]; tableController.tableView = self.containerTableView; tableController.refreshControl = self.refreshControl;
这样你就可以把你的UITableView包装在一个控制器里面,这个控制器的[self.refreshControl endRefreshing]
将在viewWillAppear
或者viewWillDisappear
里面工作。 在某些情况下,您可能需要在两者中调用它。
希望这可以帮助! 🙂
我无法调用endRefreshing在导航发生之前工作,所以我从另一端和viewWillAppear接近问题,我检查tableView contentOffset是否为负数将tableView返回到0。
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.tableView.contentOffset.y < 0) { [self.tableView setContentOffset:CGPointZero animated:YES]; } }
这个问题的答案解决了我的问题
基本上停下来,再次启动飞旋视图将会出现
几次运行到相同的问题后,我决定为它做一个库SwiftPullToRefresh 。
如前所述, refreshControl
需要在viewDidDisappear(_:)
上refreshControl
,并在viewWillAppear(_:)
上启动。
当以编程方式启动refreshControl
animation时,需要将tableView.contentOffset
设置为适当的值。
tableView.setContentOffset(CGPoint(x: 0, y: -(refreshControl?.bounds.height ?? 60) - topOffset), animated: true) var topOffset: CGFloat { if let navigationBar = navigationController?.navigationBar, navigationBar.isTranslucent == true { return navigationBar.bounds.height + UIApplication.shared.statusBarFrame.height } else { return 0 } }
Swift最好的修复:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) //fixes bug with refreshControl freezing while switching tabs if tableView.contentOffset.y < 0 { tableView.contentOffset = .zero } }