UIRefreshControlをtableViewHeaderがあるUITableViewに追加すると上から
UIRefreshControl→tableViewHeader→tableView
の順番に配置されます。
(※ 別にcontentInsetのtopを設定した場合の値は、UIRefreshControlとtableViewHeaderの間になります。)
これをtableHeaderViewを無視してUIRefreshControlを配置する方法です。
tableViewのスクロールに追尾する広告を表示したい時に使えると思います。(広告をUINavigationControllerのViewに配置して、talbeViewにダミーのtableViewHeaderを置き最上部のマージンをかせぐ)
by Falcon
実装
サブクラスのlayoutSubviewdsで調整します。
YSRefreshControl.h
@interface YSRefreshControl : UIRefreshControl
- (id)initWithIgnoreTableHeaderView:(BOOL)ignore;
@property (nonatomic, getter = isIgnoreTableHeaderView) BOOL ignoreTableHeaderView;
@end
YSRefreshControl.m
@implementation YSRefreshControl
- (id)initWithIgnoreTableHeaderView:(BOOL)ignore
{
if (self = [super init]) {
self.ignoreTableHeaderView = ignore;
}
return self;
}
- (void)layoutSubviews
{
// 有効かを確認
if (self.ignoreTableHeaderView && [self.superview isKindOfClass:[UITableView class]]) {
// UIRefreshControlの位置をtableHeadViewの最下部に合わせる
UITableView *tableView = (id)self.superview;
CGRect frame = self.frame;
frame.origin.y = frame.origin.y + tableView.tableHeaderView.bounds.size.height;
self.frame = frame;
}
}
- (void)didMoveToSuperview
{
/* UIRefreshControlは -didMoveTotSuperviewをOverrideしている
[super didMoveToSuperview]を呼ばないとUIRefreshControlは有効にならない*/
[super didMoveToSuperview];
/* tableViewのcontentOffsetを初期位置を調整 */
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UITableView *tb = (id)self.superview;
if (self.ignoreTableHeaderView && [tb isKindOfClass:[UITableView class]]) {
CGPoint offset = CGPointMake(
0.f,
tb.tableHeaderView.bounds.size.height);
[tb setContentOffset:offset animated:NO];
}
});
}
使用方法
Sample.h
UIRefreshControl *refCon = [[YSRefreshControl alloc] initWithIgnoreTableHeaderView:YES];
[refCon addTarget:self action:@selector(refreshControlDidChange:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refCon;