没有UITableViewController的UIRefreshControl

时间:2012-09-19 15:30:22

标签: objective-c ios uitableview ios6 uirefreshcontrol

只是好奇,因为它似乎不可能,但有没有使用新的iOS 6 UIRefreshControl类而不使用UITableViewController子类的偷偷摸摸的方式?

我经常使用带有UIViewController子视图的UITableView并符合UITableViewDataSourceUITableViewDelegate,而不是完全使用UITableViewController

11 个答案:

答案 0 :(得分:386)

在预感中,基于DrummerB的灵感,我尝试将UIRefreshControl实例作为子视图添加到我的UITableView。它神奇地起作用了!

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.myTableView addSubview:refreshControl];

这会在您的表格视图上方添加UIRefreshControl并按预期工作,而不必使用UITableViewController:)


编辑:上面的内容仍然有效,但正如一些人指出的那样,以这种方式添加UIRefreshControl时会出现轻微的“口吃”。解决方法是实例化UITableViewController,然后将UIRefreshControl和UITableView设置为,即:

UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

答案 1 :(得分:21)

您将尝试使用您正在使用的ViewController中的容器视图。您可以使用专用的tableview定义干净的UITableViewController子类,并将其放在ViewController中。

答案 2 :(得分:18)

UIRefreshControl是一个UIView子类,所以你可以自己使用它。我不确定它是如何渲染自己的。渲染可能只取决于框架,但它也可以依赖于UIScrollView或UITableViewController。

无论哪种方式,它都将是一个黑客而不是一个优雅的解决方案。我建议您查看一个可用的第三方克隆或自己编写。

ODRefreshControl

enter image description here

SlimeRefresh

enter image description here

答案 3 :(得分:7)

在tableView重新加载其内容后,尝试通过使用NSObject的-endRefresh或GCD的-performSelector:withObject:afterDelay:来延迟对refreshControl dispatch_after方法的调用。

我为此在UIRefreshControl上创建了一个类别:

@implementation UIRefreshControl (Delay)

- (void)endRefreshingAfterDelay:(NSTimeInterval)delay {
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self endRefreshing];
    });
}

@end

我测试了它,这也适用于集合视图。我注意到延迟一样小 0.01秒就足够了:

// My data refresh process here while the refresh control 'isRefreshing'
[self.tableView reloadData];
[self.refreshControl endRefreshingAfterDelay:.01];

答案 4 :(得分:6)

  

IOS 10 Swift 3.0

它很简单

std::exception

enter image description here

如果您想了解iOS 10 UIRefreshControl,请阅读here

答案 5 :(得分:3)

将刷新控件添加为子视图会在节标题上方创建一个空白区域。

相反,我将UITableViewController嵌入到我的UIViewController中,然后将我的tableView属性更改为指向嵌入式属性,并且中提琴!最小的代码更改。 : - )

步骤:

  1. 在Storyboard中创建一个新的UITableViewController并将其嵌入到原始的UIViewController中
  2. @IBOutlet weak var tableView: UITableView!替换为新嵌入的UITableViewController中的一个,如下所示

  3. class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        weak var tableView: UITableView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let tableViewController = self.childViewControllers.first as! UITableViewController
            tableView = tableViewController.tableView
            tableView.dataSource = self
            tableView.delegate = self
    
            // Now we can (properly) add the refresh control
            let refreshControl = UIRefreshControl()
            refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: .ValueChanged)
            tableViewController.refreshControl = refreshControl
        }
    
        ...
    }
    

答案 6 :(得分:2)

适用于Swift 2.2。

首先制作UIRefreshControl()。

var refreshControl : UIRefreshControl!

在viewDidLoad()方法中添加:

refreshControl = UIRefreshControl()
    refreshControl.attributedTitle = NSAttributedString(string: "Refreshing..")
    refreshControl.addTarget(self, action: #selector(YourUIViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
    self.tableView.addSubview(refreshControl)

制作刷新功能

func refresh(refreshControl: UIRefreshControl) {

    // do something ...

    // reload tableView
    self.tableView.reloadData()

    // End refreshing
    refreshControl.endRefreshing()
}

答案 7 :(得分:0)

这是另一种有点不同的解决方案。

我必须使用它,因为我遇到了一些视图层次结构问题:我正在创建一些功能,需要将视图传递到视图层次结构中的不同位置,这在使用UITableViewController的tableview b / c时会中断tableView是UITableViewController的根视图(self.view),而不仅仅是常规视图,它创建了不一致的控制器/视图层次结构并导致崩溃。

基本上创建自己的UITableViewController子类并覆盖loadView以为self.view分配不同的视图,并覆盖tableView属性以返回单独的tableview。

例如:

@interface MyTableVC : UITableViewController
@end

@interface MyTableVC ()
@property (nonatomic, strong) UITableView *separateTableView;
@end

@implementation MyTableVC

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectZero];
}

- (UITableView *)tableView {
    return self.separateTableView;
}

- (void)setTableView:(UITableView *)tableView {
    self.separateTableView = tableView;
}

@end

当与Keller的解决方案结合使用时,这将更加健壮,因为tableView现在是常规视图,而不是VC的根视图,并且对于更改视图层次结构更加健壮。以这种方式使用它的例子:

MyTableVC *tableViewController = [[MyTableVC alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

还有另一种可能的用途:

由于以这种方式进行子类化将self.view与self.tableView分开,现在可以将此UITableViewController用作常规控制器,并将其他子视图添加到self.view,而无需向UITableView添加子视图的奇怪之处,所以有人可能会考虑让他们的视图控制器直接成为UITableViewController的子类,而不是让UITableViewController成为子类。

需要注意的一些事项:

由于我们在不调用super的情况下覆盖了tableView属性,因此可能需要注意一些事项并在必要时进行处理。例如,在上面的示例中设置tableview不会将tableview添加到self.view,也不会设置您可能想要执行的框架。此外,在此实现中,在实例化类时没有为您提供默认的tableView,这也是您可以考虑添加的内容。我不会在这里包含它,因为这是个案,这个解决方案实际上非常符合Keller的解决方案。

答案 8 :(得分:0)

试试这个,

以上解决方案很好但是tableView.refreshControl仅适用于UITableViewController,直到iOS 9.x并且从iOS 10.x开始进入UITableView。

用Swift 3编写 -

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(FeedViewController.loadNewData), for: UIControlEvents.valueChanged)
// Fix for the RefreshControl Not appearing in background
tableView?.addSubview(refreshControl)
tableView.sendSubview(toBack: refreshControl)

答案 9 :(得分:-1)

Keller的第一个建议导致iOS 7中出现一个奇怪的错误,在视图控制器重新出现后,表的插入会增加。使用uitableviewcontroller更改为第二个答案,为我修复了一些问题。

答案 10 :(得分:-6)

当您使用带有UITableView子视图的UIViewController并符合UITableViewDataSource和UITableViewDelegate时,您可以使用以下内容:

self.refreshControl = [[UIRefreshControl alloc]init];
[self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];