如何更新已显示的上下文菜单中的值?

use*_*637 5 iphone contextmenu ios swift

我正在关注本教程https://kylebashour.com/posts/context-menu-guide并试图重新利用此显示上下文菜单的代码段:

class TableViewController: UITableViewController {
    let data: [MyModel] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // Configure the table view
    }

    override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
        let item = data[indexPath.row]

        return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in

            // Create an action for sharing
            let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up")) { action in
                print("Sharing \(item)")
            }

            // Create other actions...

            return UIMenu(title: "", children: [share, rename, delete])
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

显示上下文菜单 5 秒后,我想更新菜单的标题

UIMenu(title: "expired", children: [share, rename, delete])
Run Code Online (Sandbox Code Playgroud)

并确保其子项具有.disabled属性集。

UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up", , attributes: .disabled)
Run Code Online (Sandbox Code Playgroud)

有没有办法可以更新已经显示的上下文菜单的标题及其子项的属性?

Gas*_*tes -2

如果您想要动态表,您应该使用数据模型,并在每次想要更改表视图上显示的数据时更新它们。

我的意思是说?一个好的方法是为表视图中的每一行建立一个模型,其中包含要在该行中显示的数据 (CellModel)。

因此,在表视图控制器中,您将有一个 CellModel 列表:

private var cellModels = [ CellModel ]()
Run Code Online (Sandbox Code Playgroud)

在视图上创建单元模型确实加载函数并实现 UITableViewDatasource 函数:

// MARK: - UITableViewDatasource implementation.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.cellModels.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellModel = self.cellModels[indexPath.row]

    let cell = tableView.dequeueReusableCell(withIdentifier: kTableViewCellIdentifier, for: indexPath)
    cell.textLabel?.text = cellModel.cellData.menuDataTitle

    return cell
}
Run Code Online (Sandbox Code Playgroud)

现在是时候使用 CellModel 类了:该类代表您将在一行中显示的数据。在这个简单教程的每一行中,您都显示一个带有标题的字符串,但想象一下您想要显示标题、副标题和图像,在这种情况下,创建一个类来表示您要处理的数据很方便显示在行上。我将其命名为“CellData”:

class CellData {
    // MARK: - Vars.
    private(set) var menuDataTitle: String

    // MARK: - Initialization.
    init(title: String) {
        self.menuDataTitle = title
    }
 }
Run Code Online (Sandbox Code Playgroud)

另一方面,对于每一行,您都有一个要显示的菜单,因此有一个代表您要显示的菜单的模型很方便。我将其命名为“CellContextMenuData”:

class CellContextMenuData {
    // MARK: - Vars.
    private(set) var contextMenuTitle: String
    private(set) var contextMenuActions = [ UIAction ]()

    // MARK: - Initialization.
    init(title: String) {
        self.contextMenuTitle = title
    }
}
Run Code Online (Sandbox Code Playgroud)

该模型有一个标题和要在菜单上显示的操作:

// MARK: - UITableViewDelegate.
override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
    let cellModel = self.cellModels[indexPath.row]
    let cellContextMenuData = cellModel.cellContextMenuData

    return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
        return UIMenu(title: cellContextMenuData.contextMenuTitle, children: cellContextMenuData.contextMenuActions)
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,每次您想要更改菜单标题(或操作)时:

1 - 检索表示您要更改的行的单元格模型。

2 - 更改 CellContextMenuData 的标题。

3 - 重新加载表格视图。

例子:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // Timer to change our data.
    Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { [weak self] timer in
        let cellModel = self?.cellModels[3]
        let cellContextMenuData = cellModel?.cellContextMenuData

        cellContextMenuData?.contextMenuUpdate(title: "Expired")
        cellContextMenuData?.contextMenuSetActionsShareUpdateDelete()

        self?.tableView.reloadData()
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个示例,请随意使用/查看它: https: //bitbucket.org/gastonmontes/contextmenuexample