UIRefreshControl находится в неправильном положении в UITableViewController

Я видел довольно много проблем с UIRefreshControl, и у меня тоже проблема с моим UITableViewController. Проблема возникает так случайным образом, и отныне я не могу понять, почему и как это происходит.

Проблема заключается в том, что иногда, когда вы просматриваете таблицуView, UIRefreshControl появляется не в том месте и что кажется выше/поверх самого tableView. Я прилагаю скриншот к проблеме, а также мой код, используемый для добавления UIRefreshControl и его метода обновления.

Я ценю любую помощь!

enter image description here

- (void)viewDidLoad
{
    self.refreshControl = [[UIRefreshControl alloc] init];

    [self.refreshControl addTarget:self action:@selector(refreshing:) forControlEvents:UIControlEventValueChanged];

    [self.tableView addSubview:self.refreshControl];

    self.tableView.tableFooterView = [[UIView alloc] init];
}

- (void)refreshing:(UIRefreshControl*)refreshControl
{
    [refreshControl beginRefreshing];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    [refreshControl endRefreshing];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
 }

Ответ 1

Это известная ошибка с iOS7; иногда элемент управления обновлением помещается неправильно перед иерархией представлений, а не обратно. Вы можете противостоять части проблемы, отправив ее обратно после компоновки:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self.refreshControl.superview sendSubviewToBack:self.refreshControl];
}

Анимация по-прежнему будет несовершенной, но по крайней мере она будет по-прежнему ниже табличного представления. Пожалуйста, откройте отчет об ошибке с Apple для этой проблемы.

Кроме того, как указано в другом ответе, вы не должны добавлять элемент управления обновлением в иерархию представлений самостоятельно. Контроллер табличного представления сделает это за вас. Но это не проблема.

Быстрая версия

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    refreshControl?.superview?.sendSubview(toBack: refreshControl!)
}

Ответ 2

У меня была такая же проблема, и я исправил это:

override func viewDidLoad() {
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
    tableView.backgroundView = refreshControl // <- THIS!!!
}

Вместо добавления subview назначьте refreshControl как backgroundView