只是好奇,因为它似乎不可能,但有没有使用新的iOS 6 UIRefreshControl
类而不使用UITableViewController
子类的偷偷摸摸的方式?
我经常使用带有UIViewController
子视图的UITableView
并符合UITableViewDataSource
和UITableViewDelegate
,而不是完全使用UITableViewController
。
答案 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。
无论哪种方式,它都将是一个黑客而不是一个优雅的解决方案。我建议您查看一个可用的第三方克隆或自己编写。
答案 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)
答案 5 :(得分:3)
将刷新控件添加为子视图会在节标题上方创建一个空白区域。
相反,我将UITableViewController嵌入到我的UIViewController中,然后将我的tableView
属性更改为指向嵌入式属性,并且中提琴!最小的代码更改。 : - )
步骤:
@IBOutlet weak var tableView: UITableView!
替换为新嵌入的UITableViewController中的一个,如下所示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];