TableView contextMenuConfigurationForRowAt bug

Reloading tableView while context menu for cell is shown breaks cell's contents, bug behaviour differs on platforms. Create default storyboard project and replace ViewController.swift with this code. See willEnterForeground

import UIKit

final class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let vc = TableViewController()
        present(vc, animated: false)
    }
}

final class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(willEnterForeground),
            name: UIApplication.willEnterForegroundNotification,
            object: nil
        )
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
    }

    @objc func willEnterForeground() {
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
            // open context menu for cell
            // hide app
            // open it, wait 1 sec
            // displayed cell is wrong:

            self.tableView.reloadData() // only iOS 15
            //
            // this one also breaks selected cell (iOS 14/15):
            //
            // self.tableView.reloadRows(at: [self.tableView.indexPathForSelectedRow!], with: .automatic)
        }
    }

    var data = (1...30)

    override func numberOfSections(in tableView: UITableView) -> Int {
        1
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }

    override func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    }

    override func tableView(
        _ tableView: UITableView,
        contextMenuConfigurationForRowAt indexPath: IndexPath,
        point: CGPoint
    ) -> UIContextMenuConfiguration? {
        let actionProvider: UIContextMenuActionProvider = { _ in
            UIMenu(title: "Title", children: [
                UIAction(title: "Share") { _ in },
            ])
        }

        return UIContextMenuConfiguration(
            identifier: nil,
            previewProvider: nil,
            actionProvider: actionProvider
        )
    }
}


TableView contextMenuConfigurationForRowAt bug
 
 
Q