我想做的是:
我有一个有4个UIButton的UITableViewCell。我想能够长按任何一个按钮,并偷看显示一个基于不同数据的ViewController与哪个按钮进行了交互。
我尝试过的:
@available(iOS 13.0, *)
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
let location = interaction.location(in: tableView)
guard let indexPath = tableView.indexPathForRow(at: location) else {
return nil
}
guard let cell = tableView.cellForRow(at: indexPath) else {
return nil
}
guard let button = cell.hitTest(location, with: nil) as? UIButton else {
return nil
}
let stuff : [String : Any] = ["tag" : button.tag as NSNumber, "indexPath" : indexPath as IndexPath]
let config = UIContextMenuConfiguration(identifier: stuff as NSCopying) { () -> UIViewController? in
return ProfitSpreadsheetViewController()
}
return config
}
@available(iOS 13.0, *)
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
guard let stuff = configuration.identifier as? [String : Any] else {
return nil
}
if let tag = stuff["tag"] as? Int {
guard let cell = tableView.cellForRow(at: stuff["indexPath"] as! IndexPath) else {
return nil
}
if let button = cell.viewWithTag(tag) {
return UITargetedPreview(view: button)
}
}
return nil
}不起作用的是:
没有UITableViewCell的子视图对长按做出响应,也没有调用任何委托方法。我尝试了这段代码的另一个版本,在那里我使用了tableView上下文菜单委托方法,但只有当我长时间按下实际的单元格,而不是它的任何子视图(如UIButton)时,它才能起作用,这就是导致我采用这种方法的原因。
发布于 2020-12-21 18:45:14
iOS 14版本:
创建按钮时,可以使用menu属性为每个按钮添加上下文菜单,如下所示:
let destruct = UIAction(title: "Destruct", attributes: .destructive) { _ in }
let button = UIButton()
button.menu = UIMenu(title: "", children: [destruct])这甚至可以在表视图中工作(根据我的测试)。
iOS 13版本
不幸的是,menu只在iOS 14中可用,但您可以使用一种变通方法。您将需要创建一个自定义UIButton子类,您可以在其中手动添加上下文菜单交互。
class ContextMenuButton: UIButton {
var previewProvider: UIContextMenuContentPreviewProvider?
var actionProvider: UIContextMenuActionProvider?
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
let interaction = UIContextMenuInteraction(delegate: self)
addInteraction(interaction)
}
public override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
UIContextMenuConfiguration(
identifier: nil,
previewProvider: previewProvider,
actionProvider: actionProvider
)
}
}创建按钮时,需要手动设置操作和预览
let destruct = UIAction(title: "Destruct", attributes: .destructive) { _ in }
let button = ContextMenuButton()
button.actionProvider = { _ in
UIMenu(title: "", children: [destruct])
}https://stackoverflow.com/questions/65388034
复制相似问题