web-dev-qa-db-ja.com

再読み込み時にUITableviewが上部にスクロールする

アプリで問題が発生しています。お気に入りの場所を投稿および編集できます。投稿を投稿するか、特定の投稿(UITableViewCell)を編集すると、UITableviewが再読み込みされます。

私の問題は、リロード後にUITableviewが一番上にスクロールすることです。しかし、それは私が望むものではありません。私は自分のビューを自分のいるセル/ビューにとどめたいです。しかし、私はそれを管理する方法がわかりません。

私たちを手伝ってくれますか?

15
debbiedowner

動的にサイズ変更可能なセル(UITableViewAutomaticDimension)を使用している場合、イゴールの答えは正しい

ここではSwift 3:

    private var cellHeights: [IndexPath: CGFloat?] = [:]
    var expandedIndexPaths: [IndexPath] = []

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        cellHeights[indexPath] = cell.frame.height
    }

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        if let height = cellHeights[indexPath] {
            return height ?? UITableViewAutomaticDimension
        }
        return UITableViewAutomaticDimension
    }


    func expandCell(cell: UITableViewCell) {
      if let indexPath = tableView.indexPath(for: cell) {
        if !expandedIndexPaths.contains(indexPath) {
            expandedIndexPaths.append(indexPath)
            cellHeights[indexPath] = nil
            tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
            //tableView.scrollToRow(at: indexPath, at: .top, animated: true)
        }
      }
    }
24
Kurt J

上にスクロールしないようにするには、セルが読み込まれるときにセルの高さを保存し、tableView:estimatedHeightForRowAtIndexPath

// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary;

// initialize it in ViewDidLoad or other place
cellHeightsDictionary = @{}.mutableCopy;

// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];
}

// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
    if (height) return height.doubleValue;
    return UITableViewAutomaticDimension;
}
15
Igor

UITableViewreloadData()メソッドは、明示的にtableView全体の強制再読み込みです。それはうまく機能しますが、ユーザーが現在見ているテーブルビューでそれを行おうとすると、通常は不快でユーザーエクスペリエンスが悪くなります。

代わりに、reloadRowsAtIndexPaths(_:withRowAnimation:)およびreloadSections(_:withRowAnimation:)ドキュメント内 をご覧ください。

11
SpacyRicochet

簡単な解決策が必要な場合は、これらの行に行くだけです

    let contentOffset = tableView.contentOffset
    tableView.reloadData()
    tableView.setContentOffset(contentOffset, animated: false)
5
zeiteisen