TNKRefreshControl是UIRefreshControl的替代品,它可以与任何UIScrollView一起使用,并使用更现代的外观。
要运行示例项目,请克隆仓库,然后从Example目录运行pod install
。
有关更多详细信息,请参阅文档。
与在UITableViewController上设置refreshControl不同,您为任何UIScrollView或UIScrollView子类(如UITableView)创建并设置TNKRefreshControl。
self.tableView.tnk_refreshControl = [TNKRefreshControl new];
[self.tableView.tnk_refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
从那里,您可以使用beginRefreshing
编程方式激活刷新控件。当您完成了内容加载,请确保调用endRefreshing
。
- (IBAction)refresh:(id)sender {
[self.tableView.tnk_refreshControl beginRefreshing];
[_objectSource loadNewObjects:^(NSArray *newDates) {
[self.tableView.tnk_refreshControl endRefreshing];
[self.tableView reloadData];
}];
}
UITableView
有一个坏习惯,就是将其区头放置在contentInset
之下。当刷新控件激活时,这会导致浮动区头看起来比应该低。以前,TNKRefreshControl会使用方法交换来调整头部。但是,对于框架的许多用户来说,他们并没有将带有浮动头部的刷新控件一起使用,但对所有包含该框架的项目来说,layoutSubviews
都会在UITableView
上交换。
如果您仍然需要浮动头部的修复,您可以在您的项目中包含此代码,以及JRSwizzle。此外,您必须使用-[UITableView dequeueReusableHeaderFooterViewWithIdentifier:]
(或默认头部视图)以便此功能正常工作。有关更多信息,请参阅rdar://19489536。
@implementation UITableView (TNKRefreshControl)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSError *error;
BOOL result = [[self class] jr_swizzleMethod:@selector(layoutSubviews) withMethod:@selector(TNK_layoutSubviews) error:&error];
if (!result || error) {
NSLog(@"Can't swizzle methods - %@", [error description]);
}
});
}
- (void)TNK_layoutSubviews
{
[self TNK_layoutSubviews]; // this will call layoutSubviews implementation, because we have exchanged them.
// UITableView has a nasty habbit of placing it's section headers below contentInset
// We aren't changing that behavior, just adjusting for the inset that we added
if (self.tnk_refreshControl.addedContentInset.top != 0.0) {
//http://b2cloud.com.au/tutorial/uitableview-section-header-positions/
const NSUInteger numberOfSections = self.numberOfSections;
const UIEdgeInsets contentInset = self.contentInset;
const CGPoint contentOffset = self.contentOffset;
const CGFloat sectionViewMinimumOriginY = contentOffset.y + contentInset.top - self.tnk_refreshControl.addedContentInset.top;
// Layout each header view
for(NSUInteger section = 0; section < numberOfSections; section++)
{
UIView* sectionView = [self headerViewForSection:section];
if(sectionView == nil)
continue;
const CGRect sectionFrame = [self rectForSection:section];
CGRect sectionViewFrame = sectionView.frame;
sectionViewFrame.origin.y = ((sectionFrame.origin.y < sectionViewMinimumOriginY) ? sectionViewMinimumOriginY : sectionFrame.origin.y);
// If it's not last section, manually 'stick' it to the below section if needed
if(section < numberOfSections - 1)
{
const CGRect nextSectionFrame = [self rectForSection:section + 1];
if(CGRectGetMaxY(sectionViewFrame) > CGRectGetMinY(nextSectionFrame))
sectionViewFrame.origin.y = nextSectionFrame.origin.y - sectionViewFrame.size.height;
}
[sectionView setFrame:sectionViewFrame];
}
}
}
@end
David Beck,[email protected]
TNKRefreshControl在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。