【问题标题】:UIContextMenu and UITableView issuesUIContextMenu 和 UITableView 问题
【发布时间】:2021-04-01 01:28:41
【问题描述】:

我正在尝试添加与 iMessages 中类似的 UIContextMenu。长按消息时,应显示带有一些选项的上下文菜单。 我使用tableView(_:contextMenuConfigurationForRowAt:point:) 和其他方法。到目前为止一切顺利。

但我遇到了 2 个我无法解决的问题:

  1. 最大的一个是预览的变化。当显示上下文菜单并且您收到一条新消息(导致 tableview 重新加载)时,预览将更改其内容。突然之间,出现了与您最初选择的不同的消息。但我不明白为什么,因为没有调用上下文菜单的 tableview 方法......我怎么能解决这个问题? Apple 信息停止添加新信息。但例如 Viber 仍然能够在有上下文菜单时接收新消息。

  2. 我想在tableView(_:willDisplayContextMenu:animator:) 的帮助下以某种方式像Apple 一样处理它......但是还有第二个问题-这种方法仅适用于iOS +14.0..!所以我怎么知道在 iOS 14 之前会有上下文菜单?

我将不胜感激。谢谢。

【问题讨论】:

    标签: ios swift uitableview uikit uicontextmenuinteraction


    【解决方案1】:

    我能够以某种方式解决第一个问题。主要思想是使用快照而不是单元格的视图。这样即使 tableView 重新加载,快照也保持不变。

    您必须实现这两种方法并在那里提供快照: tableView(_:previewForHighlightingContextMenuWithConfiguration:) tableView(_:previewForDismissingContextMenuWithConfiguration:)

    在我的代码中是这样的:

    func tableView(_: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
            guard
                let messageId = configuration.identifier as? String,
                let indexPath = dataSource.indexPath(for: messageId),
                let cell = tableView.cellForRow(at: indexPath) as? YourCustomCell else {
                return nil
            }
    
            return makeTargetedPreview(cell: cell)
        }
    
     func makeTargetedPreview(cell: YourCustomCell) -> UITargetedPreview? {
            guard
                let previewView = cell.viewYouWantToDisplay,
                let snapshot = previewView.snapshotView(afterScreenUpdates: false)
            else {
                return nil
            }
    
            // 1. Prepare how should the view in the preview look like
            let parameters = UIPreviewParameters()
            parameters.backgroundColor = .clear
            parameters.visiblePath = UIBezierPath(roundedRect: previewView.bounds, cornerRadius: previewView.layer.cornerRadius)
    
            // 2. Prepare UIPreviewTarget so we can use snapshot
            let previewTarget = UIPreviewTarget(
                container: previewView,
                center: CGPoint(x: previewView.bounds.midX, y: previewView.bounds.midY)
            )
    
            // 3. Return UITargetedPreview with snapshot
            // important ! We can't use cell's previewView directly as it's getting changed when data reload happens
            return UITargetedPreview(view: snapshot, parameters: parameters, target: previewTarget)
        }
    

    注意:previewForDismissing(...) 的实现类似。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多