Обычно я делаю это, используя простое расширение ячейки:
class ForceTouchCell: UITableViewCell {
var previewingContext: UIViewControllerPreviewing?
func registerPreview(on controller: UIViewController, with delegate: UIViewControllerPreviewingDelegate) {
self.previewingContext = controller.registerForPreviewing(with: delegate, sourceView: self)
}
func unregisterPreview(on controller: UIViewController) {
guard let previewingContext = previewingContext else {
return
}
controller.unregisterForPreviewing(withContext: previewingContext)
self.previewingContext = nil
}
}
Затем на контроллере:
class MyController: UIViewController, UITableViewDelegate {
var tableView: UITableView!
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
guard traitCollection.forceTouchCapability != previousTraitCollection?.forceTouchCapability else {
return
}
let visibleCells = tableView.visibleCells
.compactMap { $0 as? ForceTouchCell }
if traitCollection.forceTouchCapability == .available {
visibleCells.forEach {
$0.registerPreview(on: self, with: self)
}
} else {
visibleCells.forEach {
$0.unregisterPreview(on: self)
}
}
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let forceTouchCell = cell as? ForceTouchCell {
if self.traitCollection.forceTouchCapability == .available {
forceTouchCell.registerPreview(on: self, with: self)
}
}
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
if let forceTouchCell = cell as? ForceTouchCell {
forceTouchCell.unregisterPreview(on: self)
}
}
}
extension MyConroller: UIViewControllerPreviewingDelegate {
func previewingContext(
_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint
) -> UIViewController? {
guard
let cell = (previewingContext.sourceView as? ForceTouchCell),
let indexPath = tableView.indexPath(for: cell)
else {
return nil
}
// use the indexPath/cell to create preview controller
}
Хорошая особенность этого решения заключается в том, что оно можетбыть легко распределенным между контроллерами, например, используя протоколы с реализациями по умолчанию.