iewAutomaticDimension更新UITableVi

iewAutomaticDimension更新UITableVi

本文介绍了使用UITableViewAutomaticDimension更新UITableViewCell后的生涩滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个应用,其中包含用户提交的帖子的Feed视图。此视图具有 UITableView ,其中包含自定义 UITableViewCell 实现。在这个单元格中,我有另一个 UITableView 用于显示注释。要点是这样的:

I am building an app that has a feed view for user-submitted posts. This view has a UITableView with a custom UITableViewCell implementation. Inside this cell, I have another UITableView for displaying comments. The gist is something like this:

Feed TableView
  PostCell
    Comments (TableView)
      CommentCell
  PostCell
    Comments (TableView)
      CommentCell
      CommentCell
      CommentCell
      CommentCell
      CommentCell

初始订阅源将下载3条评论进行预览,但如果有更多评论,或者用户添加或删除评论,我想更新通过在<$中的注释表中添加或删除 CommentCells ,将 PostCell 放在feed表视图中。 C $ C> PostCell 。我目前正在使用以下帮助程序来实现:

The initial feed will download with 3 comments for previewing, but if there are more comments, or if the user adds or deletes a comment, I want to update the PostCell in place inside of the feed table view by adding or removing CommentCells to the comments table inside of the PostCell. I am currently using the following helper to accomplish that:

// (PostCell.swift) Handle showing/hiding comments
func animateAddOrDeleteComments(startRow: Int, endRow: Int, operation: CellOperation) {
  let table = self.superview?.superview as UITableView

  // "table" is outer feed table
  // self is the PostCell that is updating it's comments
  // self.comments is UITableView for displaying comments inside of the PostCell
  table.beginUpdates()
  self.comments.beginUpdates()

  // This function handles inserting/removing/reloading a range of comments
  // so we build out an array of index paths for each row that needs updating
  var indexPaths = [NSIndexPath]()
  for var index = startRow; index <= endRow; index++ {
    indexPaths.append(NSIndexPath(forRow: index, inSection: 0))
  }

  switch operation {
  case .INSERT:
    self.comments.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)
  case .DELETE:
    self.comments.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)
  case .RELOAD:
    self.comments.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)
  }

  self.comments.endUpdates()
  table.endUpdates()

  // trigger a call to updateConstraints so that we can update the height constraint
  // of the comments table to fit all of the comments
  self.setNeedsUpdateConstraints()
}

override func updateConstraints() {
  super.updateConstraints()
  self.commentsHeight.constant = self.comments.sizeThatFits(UILayoutFittingCompressedSize).height
}

这样就完成了更新。该帖子已按预期更新或删除 PostCell 内的评论。我在feed表中使用自动调整大小 PostCells PostCell 的评论表会展开以显示所有评论,但动画有点不稳定,而且表格会在十几个像素左右上下滚动,而细胞更新动画发生。

This accomplishes the update just fine. The post is updated in place with comments added or removed inside of the PostCell as expected. I am using auto sizing PostCells in the feed table. The comments table of the PostCell expands to show all of the comments, but the animation is a bit jerky and the table sort of scrolls up and down a dozen pixels or so while the cell update animation takes place.

调整大小时的跳跃有点烦人,但我的主要问题是后来发生的。现在,如果我在Feed中向下滚动,滚动就像以前一样平滑,但是如果我在单元格上方向上滚动,我只是在添加注释后调整大小,在Feed到达顶部之前,Feed会向后跳几次。我为Feed设置了 iOS8 自动调整大小的单元格:

The jumping during resizing is a bit annoying, but my main issue comes afterwards. Now if I scroll down in the feed, the scrolling is smooth as before, but if I scroll up above the cell I just resized after adding comments, the feed will jump backwards a few times before it reaches the top of the feed. I setup iOS8 auto sizing cells for the Feed like this:

// (FeedController.swift)
// tableView is the feed table containing PostCells
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 560

如果我删除 estimatedRowHeight ,表格只会在单元格高度滚动到顶部变化。我现在感觉非常困难,作为一个新的iOS开发者,可以使用你可能有的任何提示。

If I remove the estimatedRowHeight, the table just scrolls to the top anytime a cell height changes. I'm feeling pretty stuck on this now and as a new iOS developer, could use any tips you might have.

推荐答案

这里是我发现解决这类问题的最佳解决方案(滚动问题+ reloadRows + iOS 8 UITableViewAutomaticDimension);

Here is the best solution I found to solve this kind of problem (scrolling problem + reloadRows + iOS 8 UITableViewAutomaticDimension);

它包括将每个高度保持在字典中并更新它们(在字典中)因为tableView将显示单元格。

It consists by keeping every heights in a dictionary and updating them (in the dictionary) as the tableView will display the cell.

然后你将在 - (CGFloat)tableView中返回保存的高度:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath method。

You will then return the saved height in - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath method.

您应该实现以下内容:

Objective-C

- (void)viewDidLoad {
    [super viewDidLoad];

    self.heightAtIndexPath = [NSMutableDictionary new];
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = [self.heightAtIndexPath objectForKey:indexPath];
    if(height) {
        return height.floatValue;
    } else {
        return UITableViewAutomaticDimension;
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = @(cell.frame.size.height);
    [self.heightAtIndexPath setObject:height forKey:indexPath];
}

Swift 3

@IBOutlet var tableView : UITableView?
var heightAtIndexPath = NSMutableDictionary()

override func viewDidLoad() {
    super.viewDidLoad()

    tableView?.rowHeight = UITableViewAutomaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    if let height = heightAtIndexPath.object(forKey: indexPath) as? NSNumber {
        return CGFloat(height.floatValue)
    } else {
        return UITableViewAutomaticDimension
    }
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let height = NSNumber(value: Float(cell.frame.size.height))
    heightAtIndexPath.setObject(height, forKey: indexPath as NSCopying)
}

这篇关于使用UITableViewAutomaticDimension更新UITableViewCell后的生涩滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 06:08