Help us understand the problem. What is going on with this article?

UIRefreshControl tableHeaderViewを無視して配置する方法

More than 5 years have passed since last update.

UIRefreshControlをtableViewHeaderがあるUITableViewに追加すると上から
UIRefreshControl→tableViewHeader→tableView
の順番に配置されます。
(※ 別にcontentInsetのtopを設定した場合の値は、UIRefreshControlとtableViewHeaderの間になります。)
ss1

これをtableHeaderViewを無視してUIRefreshControlを配置する方法です。
ss2

tableViewのスクロールに追尾する広告を表示したい時に使えると思います。(広告をUINavigationControllerのViewに配置して、talbeViewにダミーのtableViewHeaderを置き最上部のマージンをかせぐ)
ss3
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;
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away