[iOS26]UITableView drag bug

I encountered a bug with drag-and-drop sorting in ios 26.

I created a UITableView for dragging and dropping to adjust the order of the list. However, when I set the height of the cells to a custom height, some cells were not displayed during the dragging process.

The tools I use are the official version of Xcode16.1 and the ios 26 emulator And I can also reproduce the same problem on the real device.

class ViewController: UIViewController {

    private let tableView: UITableView = {
        let tableView = UITableView.init(frame: .zero, style: .grouped)
        tableView.backgroundColor = .clear

        tableView.estimatedSectionHeaderHeight = 50
        tableView.isEditing = true
        tableView.showsVerticalScrollIndicator = false
        tableView.allowsSelectionDuringEditing = true
        return tableView
    }()
    
    var content: [Int] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.register(FTWatchGroupPageCell.self, forCellReuseIdentifier: "FTWatchGroupPageCell")
        tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
        
        for i in 1...100 {
            content.append(i)
        }
        
        tableView.reloadData()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        var frame = view.bounds
        frame.origin.y = 200
        frame.size.height = frame.size.height - 200
        tableView.frame = frame
    }
    
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return content.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FTWatchGroupPageCell", for: indexPath) as! FTWatchGroupPageCell
        
        cell.label.text = "\(content[indexPath.row])"
        cell.label.sizeToFit()
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 52.66
    }
    
    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    public func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
        return .none
    }
    
    public func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
        return false
    }
    
    public func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        
        let item = content.remove(at: sourceIndexPath.row)
        content.insert(item, at: destinationIndexPath.row)
        
        tableView.reloadData()
    }
}


class FTWatchGroupPageCell: UITableViewCell {
    
    private let contentBackView = UIView()
    
    let label = UILabel()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        contentView.isHidden = true
        
        addSubview(contentBackView)
        contentBackView.backgroundColor = .red
                
        contentBackView.addSubview(label)
        label.textColor = .black
        label.font = .systemFont(ofSize: 14)
        
        contentBackView.frame = .init(x: 0, y: 0, width: 200, height: 30)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        guard let reorderControlClass = NSClassFromString("UITableViewCellReorderControl"),
              let reorderControl = subviews.first(where: { $0.isKind(of: reorderControlClass) }) else {
            return
        }
        reorderControl.alpha = 0.02
        reorderControl.subviews.forEach({ subView in
            if let imageView = subView as? UIImageView {
                imageView.image = UIImage()
                imageView.contentMode = .scaleAspectFit
                imageView.frame.size = CGSize(width: 20, height: 20)
            }
        })
        
        
    }
}

Answered by DTS Engineer in 862378022

Review the drag and drop implementation in Adopting drag and drop in a table view sample project and let us know if you're able to reproduce the issue in that sample project? If you are, please let us know and we'll be able to investigate the issue. Thanks

Review the drag and drop implementation in Adopting drag and drop in a table view sample project and let us know if you're able to reproduce the issue in that sample project? If you are, please let us know and we'll be able to investigate the issue. Thanks

I didn't use drop and drag delegate. I only used UITableViewDelegate, and all my code has already been pasted on top

[iOS26]UITableView drag bug
 
 
Q