Как обновить значения в уже представленном контекстном меню? - PullRequest
5 голосов
/ 27 марта 2020

Я следую этому уроку 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])
        }
    }
}

5 секунд после того, как контекстное меню представлено, я бы хотел бы обновить заголовок меню

UIMenu(title: "expired", children: [share, rename, delete])

и убедиться, что его дочерние элементы имеют атрибут .disabled.

UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up", , attributes: .disabled)

Есть ли способ, которым я могу обновить уже представленный контекст Название меню и атрибуты его дочерних элементов?

1 Ответ

0 голосов
/ 04 апреля 2020

Если вам нужна динамическая таблица, вам следует работать с моделями данных и обновлять их каждый раз, когда вы хотите изменить данные, отображаемые в табличном представлении.

Что я имею в виду? Хороший подход - иметь для каждой строки в табличном представлении модель с данными, которые вы хотите отобразить в этой строке (CellModel).

Итак, в вашем контроллере табличного представления у вас будет список CellModels:

private var cellModels = [ CellModel ]()

Создание моделей ячеек в вашем представлении загрузило функцию и реализовало функции 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
}

Теперь пришло время работать с классом CellModel: этот класс представляет данные что вы собираетесь показать в один ряд. В каждой строке этого простого урока вы показываете строку с заголовком, но представьте, что вы хотите показать заголовок, подзаголовок и изображение, в этом случае удобно создать класс для представления данных, которые вы собираетесь показать на ряду. Я назвал его «CellData»:

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

    // MARK: - Initialization.
    init(title: String) {
        self.menuDataTitle = title
    }
 }

С другой стороны, для каждой строки у вас есть меню для показа, поэтому удобно иметь модель, которая представляет то меню, которое вы собираетесь показывать. Я назвал его «CellContextMenuData»:

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

    // MARK: - Initialization.
    init(title: String) {
        self.contextMenuTitle = title
    }
}

У этой модели есть заголовок и действия для отображения в меню:

// 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)
    }
}

Итак, каждый раз, когда вы хотите изменить меню title (или Actions):

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()
    }
}

Я создал пример, не стесняйтесь использовать / посмотреть его: https://bitbucket.org/gastonmontes/contextmenuexample

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...