scrollToRowAtIndexPath всегда прокручивается сверху вместо текущего смещения
В моем UITableView
Я использую метод для прокрутки до последней ячейки:
WLNetworkClient.sharedClient().createCommentWIthText(commentTextView.text, forItem: item) { error in
defer {
UIAlertController.showAlertFromError(error)
}
if error == nil {
self.fetchedResultsController.fetchRequest.fetchLimit += 1
try! self.fetchedResultsController.performFetch()
self.tableView.reloadData()
self.scrollTableViewToBottom()
}
}
private func scrollTableViewToBottom() {
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: fetchedResultsController.fetchedObjects!.count - 1, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)
}
но это не работает, как ожидается, потому что таблица ВСЕГДА прокручивается сверху, даже если я нахожусь на второй ячейке, чтобы продлиться. Как это исправить?
5 ответов
Ответ досдос у меня сработал в Swift 2 Добавление с незначительным обновлением
Объявить ивар
var heightAtIndexPath = NSMutableDictionary()
в func viewDidLoad()
func viewDidLoad() {
.... your code
self.tableView.rowHeight = UITableViewAutomaticDimension
}
Затем добавьте следующие 2 метода:
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let height = self.heightAtIndexPath.objectForKey(indexPath)
if ((height) != nil) {
return CGFloat(height!.floatValue)
} else {
return UITableViewAutomaticDimension
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let height = cell.frame.size.height
self.heightAtIndexPath.setObject(height, forKey: indexPath)
}
SWIFT 3:
var heightAtIndexPath = NSMutableDictionary()
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
let height = self.heightAtIndexPath.object(forKey: indexPath)
if ((height) != nil) {
return CGFloat(height as! CGFloat)
} else {
return UITableViewAutomaticDimension
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let height = cell.frame.size.height
self.heightAtIndexPath.setObject(height, forKey: indexPath as NSCopying)
}
Расширение ZaEeM ZaFaR отличный ответ:
Цель С
NSMutableDictionary *heightAtIndexPath;
heightAtIndexPath = [[NSMutableDictionary alloc] init];
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSNumber *height = [heightAtIndexPath objectForKey:indexPath];
if(height) {
return height.floatValue;
} else {
return UITableViewAutomaticDimension;
}
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[heightAtIndexPath setObject:@(cell.frame.size.height) forKey:indexPath];
}
Эта проблема покрыта здесь: Как узнать, когда UITableVIew завершил ReloadData?
Измените свой код на:
self.tableView.reloadData()
self.tableView.layoutIfNeeded()
self.scrollTableViewToBottom()
LayoutIfNeeded заставляет перезагрузку таблицы происходить немедленно. Все объяснено в ссылке.
Чтобы быть более быстрым, я бы упростил версию Swift 3, представленную выше:
var heightAtIndexPath = [IndexPath: CGFloat]()
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = self.heightAtIndexPath[indexPath] {
return height
}
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let height = cell.frame.size.height
self.heightAtIndexPath[indexPath] = height
}
Я думаю, что проблема в том, что вы прокручиваете перед обновлением tableView (по self.tableView.reloadData()
). Попробуйте отложить прокрутку:
dispatch_async(dispatch_get_main_queue()) {
self.scrollTableViewToBottom()
}
Или принудительно обновите tableView:
self.tableView.reloadData()
self.tableView.layoutIfNeeded()
self.scrollTableViewToBottom()