Ошибка: 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()
}
это работа для меня