ios - UITableView插入行动画与自定义单元格不一致

标签 ios swift uitableview

我在下面创建了一个现场操场来说明这个问题。使用自调整大小的表格单元格时,插入行动画(自下而上)的执行方式取决于最后一个单元格的大小。如果最后一个单元格比将要插入的单元格高,则动画开始得太高,因此向下动画(而不是向上动画)。这里发生了什么?

import UIKit
import PlaygroundSupport

class Live: UIViewController {
    private var entries = ["a\na\na", "b\nb\nb", "c\nc\nc", "d\nd\nd", "e\ne\ne", "f"]
    private let newEntries = ["correct\nanimation\nhere", "correct\nanimation\nhere", "incorrect animation", "correct\nanimation\nhere", "incorrect animation", "correct\nanimation\nhere"]
    private let tableView = UITableView()
    
    override func loadView() {
        view = UIView()
        view.backgroundColor = .blue
        
        tableView.dataSource = self
        tableView.delegate = self
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 64, right: 0)
        tableView.backgroundColor = .purple
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(EntryCell.self, forCellReuseIdentifier: EntryCell.reuseId)
        view.addSubview(tableView)
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
        tableView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for (n, new) in newEntries.enumerated() {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(n*2)) {
                self.entries.append(new)
                
                self.tableView.performBatchUpdates({
                    self.tableView.insertRows(at: [IndexPath(row: self.entries.count - 1, section: 0)], with: .bottom)
                }) { (finished) in
                    if finished {
                        DispatchQueue.main.async {
                            self.tableView.scrollToRow(at: IndexPath(row: self.entries.count - 1, section: 0), at: .bottom, animated: true)
                        }
                    }
                }
            }
        }
    }
}

extension Live: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return entries.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: EntryCell.reuseId, for: indexPath) as! EntryCell
        cell.entryLabel.text = entries[indexPath.row]
        return cell
    }
}

extension Live: UITableViewDelegate {
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return UIView()
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0
    }
}

extension Live {
    private class EntryCell: UITableViewCell {
        static let reuseId = "cell"
        let entryLabel = UILabel()

        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            isOpaque = true
            selectionStyle = .none
            backgroundColor = .brown
            
            entryLabel.textColor = .white
            entryLabel.numberOfLines = 0
            entryLabel.translatesAutoresizingMaskIntoConstraints = false
            addSubview(entryLabel)
            entryLabel.topAnchor.constraint(equalTo: topAnchor, constant: 16).isActive = true
            entryLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16).isActive = true
            entryLabel.widthAnchor.constraint(equalTo: widthAnchor, constant: -32).isActive = true
            entryLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -16).isActive = true
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError()
        }
    }
}

PlaygroundPage.current.liveView = Live()

最佳答案

只需将插入行从底部更改为自动,它将按滚动加载单元格。

self.tableView.insertRows(at: [IndexPath(row: self.entries.count - 1, section: 0)], with: .automatic)

关于ios - UITableView插入行动画与自定义单元格不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62648188/

相关文章:

ios - SpriteKit bodyWithTexture 未对齐

swift - 无法将 SKNode 从 .sks 文件转换为自定义类

iphone - 分组的 UITableView 中未显示文本

swift - UICollection View 与 TableView 错误索引超出范围为什么

ios - 分组 UITableview 中减少单元格

ios - 以编程方式快速加载图像

ios - Xcode 6 中的未知类型名称错误

ios - key 更改后的 RLMException - 已使用不同的加密 key 打开

swift - Playground 中的 UIView

swift - Xcode 6.1 标题文本属性