I have a ProfileVC that contain a list. I can click on any of the row cell will show peek and pop feature.
ProfileVC.swift
I added the extention
extension ProfileViewController : UIViewControllerPreviewingDelegate {
func detailViewController(for indexPath: IndexPath) -> ProfileDetailViewController {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "ProfileDetailViewController") as? ProfileDetailViewController else {
fatalError("Couldn't load detail view controller")
}
let cell = profileTableView.cellForRow(at: indexPath) as! ProfileTableViewCell
// Pass over a reference to the next VC
vc.title = cell.profileName?.text
vc.cpe = loginAccount.cpe
vc.profile = loginAccount.cpeProfiles[indexPath.row - 1]
consoleLog(indexPath.row - 1)
//print("3D Touch Detected !!!",vc)
return vc
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
if let indexPath = profileTableView.indexPathForRow(at: location) {
// Enable blurring of other UI elements, and a zoom in animation while peeking.
previewingContext.sourceRect = profileTableView.rectForRow(at: indexPath)
return detailViewController(for: indexPath)
}
return nil
}
//ViewControllerToCommit
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
// Push the configured view controller onto the navigation stack.
navigationController?.pushViewController(viewControllerToCommit, animated: true)
}
}
Then, in the same file ProfileVC.swift in viewDidLoad()
I registered it
if (self.traitCollection.forceTouchCapability == .available){
print("-------->", "Force Touch is Available")
registerForPreviewing(with: self, sourceView: view)
}
else{
print("-------->", "Force Touch is NOT Available")
}
I have no idea why I can not click on the 4th cell.
The last cell of the row does not trigger Peek & Pop.
How would one go about and debug this further?
You are registering your view controller's root view
as the source view for the peek context. As a result, the CGPoint
that is passed to previewingContext(_ viewControllerForLocation:)` is in the coordinate space of that view.
When you try and retrieve the corresponding row from your table view the point will actually be offset from the corresponding point in the table view's frame
based on the relative position of the table view in the root view.
This offset means that a corresponding row can’t be retrieved for the last row in the table; indexPathForRow(at:)
returns nil
and your function returns without doing anything.
You might also find that if you force touch towards the bottom of a cell you actually get a peek for the next row.
You could translate the CGPoint
into the table view’s frame, but it is simpler to just specify your tableview as the source view when you register for previewing:
if (self.traitCollection.forceTouchCapability == .available){
print("-------->", "Force Touch is Available")
registerForPreviewing(with: self, sourceView: self.profileTableView)
}
else{
print("-------->", "Force Touch is NOT Available")
}