Ошибка: UITableView переместится вверх с помощью UITableViewAutomaticDimension

Я использую UITableView с estimatedRowHeight и UITableViewAutomaticDimension. Также я использую NSFetchedResultsControllerDelegate для отражения изменений.

Все отлично работает. Теперь проблема заключается в том, когда когда-либо добавляю какую-либо запись в CoreData, NSFetchedResultsController, называемую ее делегатом, но происходят неожиданные вещи. TableView неожиданно прокручивается до Верх каждый раз.

NSFetchedResultsControllerDelegate

func controllerWillChangeContent(controller: NSFetchedResultsController) {
    tableView.beginUpdates()
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
}

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
        switch type {
        case .Insert:
            tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .None)
            break

        case .Update:
            tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
            break

        case .Delete:
            tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
            break

        default: break;
        }
    }

По googling я нашел несколько ответов , где люди предлагали использовать tableView: heightForRowAtIndexPath:, но поскольку моя высота ячейки динамическая. И что же мне делать?

Ответ 1

Это поведение по умолчанию tableview, вставляя строку в виде таблицы, прокручивая ее вверх. Я столкнулся с той же проблемой с моим приложением. Вот как я могу управлять смещением содержимого таблицы, следуйте инструкциям,

1) Сохраните смещение содержимого UITableview перед вставкой строки или раздела. 2) Вставить объекты в массив. 3Нагрузка таблицы 3) Вычтите разницу и вручную настройте смещение содержимого.

let oldOffset: CGFloat = tblTest.contentSize.height
tblTest.reloadData()
let newOffset: CGFloat = tblTest.contentSize.height
tblTest.setContentOffset(CGPointMake(0, (newOffset - oldOffset)), animated: false)

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

Ответ 2

Добавляя к @jayesh-miruliya ответ, в NSFetchedResultsControllerDelegate после оператора switch поместите это в свой код:

tableView.reloadData()
dispatch_async(dispatch_get_main_queue(), {
    let topCellIndexPath = NSIndexPath(forRow: 0, inSection: 0)
    self. tableView.scrollToRowAtIndexPath(topCellIndexPath, atScrollPosition: .Top, animated: true)
})

Ответ 3

Чтобы решить мою проблему, я сохраняю высоту ячейки в методе willDisplay и в estimatedHeightForRowAt Я извлекаю значение.

var cellHeights = NSMutableDictionary()

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    if let height = cellHeights.object(forKey: indexPath) {
        return height as! CGFloat
    }

    return UITableViewAutomaticDimension
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeights.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
}

Ответ 4

tableView.reloadData()
if tableView.numberOfRowsInSection(0) > 0
{
      let indexPath = NSIndexPath(forRow: 0, inSection: 0)
      self. tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}

Ответ 5

  func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
    case .Insert:

      tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .None)
        break

    case .Update:
        tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
        break

    case .Delete:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .None)
        break

    default: break;
    }
   tableView.reloadData()
  let indexPath = NSIndexPath(forRow: 0, inSection: 0)
  self. tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
   }

}

Ответ 6

let cou : Int = self.Array.count as Int
let lastindex : NSIndexPath = NSIndexPath(forRow: cou-1, inSection: 0)
self.TableName.scrollToRowAtIndexPath(lastindex, atScrollPosition: UITableViewScrollPosition.None, animated: true)

Этот код поможет вам прокрутить таблицу в определенном месте.

Ответ 7

func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    tabelView.reloadData()
}

это работа для меня