UIRefreshControl - beginRefreshing不工作时的UITableVi

2019-07-19 08:55发布

我设置在我的UITableViewController一个UIRefreshControl(这是一个UINavigationController内),它按预期工作(即拉下火灾正确的事件)。 但是,如果我编程方式调用beginRefreshing实例方法上的刷新控制,如:

[self.refreshControl beginRefreshing];

什么都没发生。 它应该动画下来并显示微调。 该endRefreshing法正常工作,当我将其称为后刷新。

我掀起了此行为的基本工程样机,当我的UITableViewController直接添加到应用程序委托的根视图控制器,例如,它正常工作:

self.viewController = tableViewController;
self.window.rootViewController = self.viewController;

但是,如果我在添加tableViewController首先一个UINavigationController,然后添加导航控制器为rootViewController ,该beginRefreshing方法不再起作用。 例如

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;

我的感觉是这事做与不打漂亮与进修控制导航控制器内嵌套视图层次 - 有什么建议?

谢谢

Answer 1:

看来,如果你开始编程提神,你必须滚动表中查看你自己,说,通过改变contentoffset

[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];

我猜这样做的原因是,这可能是不可取的,当用户在表视图中/下滚动到刷新控制?

雨燕2.2的版本由@muhasturk

self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)

概括地说,要保持这种便携式添加此扩展

UIRefreshControl + ProgramaticallyBeginRefresh.swift

extension UIRefreshControl {
    func programaticallyBeginRefreshing(in tableView: UITableView) {
        beginRefreshing()
        let offsetPoint = CGPoint.init(x: 0, y: -frame.size.height)
        tableView.setContentOffset(offsetPoint, animated: true)        
    }
}


Answer 2:

的UITableViewController具有automaticallyAdjustsScrollViewInsets属性的iOS 7.后表视图可能已经具有contentOffset,通常是(0,-64)。

所以,正确的方式来显示refreshControl后programmingly开始的刷新将refreshControl的高度,以现有contentOffset。

 [self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];


Answer 3:

下面是使用上述策略斯威夫特扩展。

extension UIRefreshControl {
    func beginRefreshingManually() {
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: true)
        }
        beginRefreshing()
    }
}


Answer 4:

其他答案都不为我工作。 它们会导致微调,以显示和旋转,但刷新动作本身永远不会发生。 这工作:

id target = self;
SEL selector = @selector(example);
// Assuming at some point prior to triggering the refresh, you call the following line:
[self.refreshControl addTarget:target action:selector forControlEvents:UIControlEventValueChanged];

// This line makes the spinner start spinning
[self.refreshControl beginRefreshing];
// This line makes the spinner visible by pushing the table view/collection view down
[self.tableView setContentOffset:CGPointMake(0, -1.0f * self.refreshControl.frame.size.height) animated:YES];
// This line is what actually triggers the refresh action/selector
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];

请注意,这个例子使用表格视图,但它也可以同样是一个集合视图。



Answer 5:

已经提到的方法:

[self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];

会使微调可见。 但它不会动画。 有一件事我改变的是这两种方法和一切工作的顺序为:

[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl beginRefreshing];


Answer 6:

也看到这个问题

UIRefreshControl不显示带刺的时候调用beginRefreshing和contentOffset为0

它看起来像我的错误,因为只有当的tableView的contentOffset属性为0 occures

我固定的用下面的代码(用于的UITableViewController法):

- (void)beginRefreshingTableView {

    [self.refreshControl beginRefreshing];

    if (self.tableView.contentOffset.y == 0) {

        [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){

            self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);

        } completion:^(BOOL finished){

        }];

    }
}


Answer 7:

用于SWIFT 4 / 4.1

现有应答的组合为我做的工作:

refreshControl.beginRefreshing()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)

希望这可以帮助!



Answer 8:

这是完美的作品对我说:

斯威夫特3:

self.tableView.setContentOffset(CGPoint(x: 0, y: -self.refreshControl!.frame.size.height - self.topLayoutGuide.length), animated: true)


Answer 9:

这是斯威夫特3扩展,显示微调以及制作动画。

import UIKit
extension UIRefreshControl {

func beginRefreshingWithAnimation() {

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {

        if let scrollView = self.superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - self.frame.height), animated: true)
          }
        self.beginRefreshing()
      }
   }
}


Answer 10:

除了@Dymitry舍甫琴科的解决方案。

我找到好的解决方法这个问题。 您可以创建扩展UIRefreshControl覆写方法:

// Adds code forgotten by Apple, that changes content offset of parent scroll view (table view).
- (void)beginRefreshing
{
    [super beginRefreshing];

    if ([self.superview isKindOfClass:[UIScrollView class]]) {
        UIScrollView *view = (UIScrollView *)self.superview;
        [view setContentOffset:CGPointMake(0, view.contentOffset.y - self.frame.size.height) animated:YES];
    }
}

您可以通过在身份督察在Interface Builder刷新控制设置自定义类使用新类。



Answer 11:

堡斯威夫特2.2+

    self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)


Answer 12:

如果您使用的Rxswift迅速3.1,可以使用如下:

func manualRefresh() {
    if let refreshControl = self.tableView.refreshControl {
        self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.height), animated: true)
        self.tableView.refreshControl?.beginRefreshing()
        self.tableView.refreshControl?.sendActions(for: .valueChanged)
    }
}

这项工作迅速3.1,iOS的10。



Answer 13:

我使用相同的技术为用户显示“数据更新”视觉标志。 一个结果用户从后台把应用程序和饲料/列表将与UI更新喜欢的网友拉表刷新自己。 我的版本包含三件事

1)谁发送“唤醒”

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationHaveToResetAllPages object:nil];
}

2)在UIViewController中观察

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(forceUpdateData) name:kNotificationHaveToWakeUp:nil];
}

3)协议

#pragma mark - ForcedDataUpdateProtocol

- (void)forceUpdateData {
    self.tableView.contentOffset = CGPointZero;

    if (self.refreshControl) {
        [self.refreshControl beginRefreshing];
        [self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
        [self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:1];
    }
}



Answer 14:

对于斯威夫特5,对我来说唯一缺少的是调用refreshControl.sendActions(.valueChanged) 我做了一个扩展,使其更加清洁。

extension UIRefreshControl {

    func beginRefreshingManually() {
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: false)
        }
        beginRefreshing()
        sendActions(for: .valueChanged)
    }

}


文章来源: UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController