UITableView и UIRfreshControl перемещаются по неизвестной причине

У меня есть UITableViewController в моем приложении с добавленным к нему UIRefreshControl. Однако иногда (я не уверен, как воспроизвести это, это случается время от времени) я получаю дополнительные пробелы в верхней части табличного представления, а элемент управления обновлением смещается даже ниже этого.

Вот как это выглядит (слева бездействует, справа вытягивается):

скриншот

Я понятия не имею, что может быть причиной этого. В моем viewdidload я только создаю экземпляр элемента управления обновлением и вызываю функцию обновления, которая устанавливает атрибутированный заголовок. Я переместил добавление элемента управления обновлением в представление таблицы в viewDidAppear, как я читал в другом месте. Вот как выглядит этот код:

override func viewDidLoad() {
    super.viewDidLoad()
    self.refreshControl = UIRefreshControl()

    updateData()
}

override func viewDidAppear(animated: Bool) {
    refreshControl!.addTarget(self, action: "updateData", forControlEvents: UIControlEvents.ValueChanged)
    tableView.insertSubview(self.refreshControl!, atIndex: 0)
}

func updateData() {
    //...
    ServerController.sendParkinglotDataRequest() {
        (sections, plotList, updateError) in
        //...

        // Reload the tableView on the main thread, otherwise it will only update once the user interacts with it
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.tableView.reloadData()

            // Update the displayed "Last update: " time in the UIRefreshControl
            let formatter = NSDateFormatter()
            formatter.dateFormat = "dd.MM. HH:mm"
            let updateString = NSLocalizedString("LAST_UPDATE", comment: "Last update:")
            let title = "\(updateString) \(formatter.stringFromDate(NSDate()))"
            let attributedTitle = NSAttributedString(string: title, attributes: nil)
            self.refreshControl!.attributedTitle = attributedTitle
        })
    }
}

person Kilian    schedule 24.03.2015    source источник
comment
Вы пытались удалить uirefreshcontrol и проверить, сохраняется ли проблема? Как выглядит ваша иерархия представлений? Есть ли у вас другие подпредставления в представлении вашего контроллера представления, которые находятся ниже вашего табличного представления?   -  person croX    schedule 24.03.2015
comment
Под табличным представлением нет дополнительных представлений, это просто панель навигации, табличное представление и ячейки табличного представления. Помимо управления обновлением, все они настраиваются в раскадровке. Я собираюсь удалить элемент управления обновлением и посмотреть, сохраняется ли проблема, но ее довольно сложно отладить, поскольку эта проблема возникает редко.   -  person Kilian    schedule 24.03.2015
comment
О, подождите, эта строка tableView.insertSubview... У меня она была до того, как я перешел на использование UITableViewController и прочитал, что UIRefreshControl не следует использовать таким образом в обычных UITableViews. В данном случае это точно не нужно, может в этом дело?   -  person Kilian    schedule 24.03.2015


Ответы (2)


Вам нужно добавить элемент управления обновлением в качестве подвида tableView? Я думаю, все, что вам нужно сделать, это назначить self.refreshControl. Согласно документации:

Значение по умолчанию этого свойства равно нулю.

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

Добавление подпредставления в viewDidAppear могло быть выполнено более одного раза. Если вы вытолкнете контроллер из ячейки и вернете его обратно, он будет вызван снова. Возможно, insertSubview проверяет, есть ли у обновления уже родитель, и сначала удаляет его, так что это может быть не ваша проблема. Вы должны делать вставку только тогда, когда контроллер появляется в первый раз.

updateData также может быть добавлено несколько раз.

Поэтому я думаю, вам нужно только назначить self.refreshControl, а затем добавить обработчик для действия обновления, как вы делаете сейчас, используя addTarget, но на этот раз сделайте это на self.refreshControl.

Вы также можете сделать все это из раскадровки. В раскадровке вы выбираете UITableViewController, а в инспекторе атрибутов просто устанавливаете для атрибута Refreshing значение «включено». Это добавляет UIRfreshControl в таблицу, и вы можете увидеть его в иерархии представлений. Затем вы можете просто перетащить CTRL, как обычно, из элемента управления обновлением в файл .h и добавить действие для valueChange, которое будет запущено, когда вы потянете элемент управления обновлением в таблице.

person Rory McKinnel    schedule 24.03.2015
comment
Я полагаю, что вы можете быть правы, я начал добавлять элемент управления обновлением в качестве подпредставления к обычному UITableView и только позже преобразовал свой контроллер представления в UITableViewController. Но я больше никогда не думал об этой линии. Это довольно сложно проверить, так как проблема возникала время от времени, но это кажется логичным. Как мне добавить обработчик в раскадровку? Элемент управления обновлением на самом деле не существует в раскадровке. - person Kilian; 24.03.2015
comment
Обновлен ответ, чтобы объяснить, как добавить UIRfreshControl в раскадровку. Это так же просто, как включить обновление в инспекторе атрибутов, и он добавит его для вас. Затем вы можете добавить свое действие с помощью перетаскивания CTRL в файл .h. При этом вы можете удалить весь свой код и просто реализовать действие. - person Rory McKinnel; 25.03.2015
comment
Раскадровка была решением для меня. Жаль, что я до сих пор не могу найти объяснения, почему это происходит. Я делаю это с документами Apple, но это дает эту неприятную ошибку пользовательского интерфейса. - person Allison; 22.04.2016

Что ж, я считаю, что описанное вами поведение не обязательно может быть вызвано контролем обновления. В связи с тем, что у вас нет других подпредставлений под вашим табличным представлением, я бы порекомендовал вам попытаться разместить «поддельное» представление под вашим табличным представлением. Обычно я предпочитаю пустую этикетку с нулевой длиной стороны.

введите здесь описание изображения

У меня были такие же проблемы, как и у вас, когда в некоторых случаях вставки в табличном представлении были сломаны. И как только я воспользовался этим "фальшивым" подпредставлением, проблемы исчезли. Я читал об этой проблеме и в других темах. И решение было таким. Кажется, это странное поведение/ошибка.

Попробуйте :)

person croX    schedule 24.03.2015
comment
Кажется невозможным добавить что-то прямо над табличным представлением в UITableViewController? Кажется, что-то, что могло бы сработать, но я просто не могу вставить туда ярлык :D - person Kilian; 24.03.2015
comment
Вы правы, я думал, что вы используете UIViewController. Я не видел этого, когда читал ваш вопрос. Но помните об этом обходном пути, если у вас есть табличное представление в обычном контроллере представления. - person croX; 24.03.2015