3

在我的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)
}

但这并没有按预期工作,因为即使我在倒数第二个单元格上,表格也总是从顶部滚动。如何解决这个问题?

4

5 回答 5

8

dosdos答案在Swift 2中对我有用

声明 ivar

var heightAtIndexPath = NSMutableDictionary()

在函数 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)
}

斯威夫特 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)
}
于 2017-01-12T10:03:37.040 回答
1

扩展 ZaEeM ZaFaR 很好的答案:

目标 C

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];
}
于 2018-05-11T12:21:03.057 回答
0

为了更快捷,我将简化上面介绍的 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
    }
于 2017-08-24T10:53:57.143 回答
0

我认为问题是您在 tableView 更新之前滚动(按self.tableView.reloadData())。尝试延迟滚动:

     dispatch_async(dispatch_get_main_queue()) {
         self.scrollTableViewToBottom()
    }

或者强制 tableView 更新:

    self.tableView.reloadData()
    self.tableView.layoutIfNeeded()
    self.scrollTableViewToBottom()
于 2015-09-09T10:01:57.950 回答
0

这个问题在这里讨论:如何判断 UITableVIew 何时完成 ReloadData?

将您的代码更改为:

self.tableView.reloadData()
self.tableView.layoutIfNeeded()
self.scrollTableViewToBottom()

layoutIfNeeded 强制表重新加载立即发生。所有在链接中解释。

于 2015-09-09T10:08:38.970 回答