-->

Peek/Pop preview ignores cell corner radius in col

2020-07-22 19:38发布

问题:

I have added 3D Touch Peek/Pop functionality to my collection view cells and it works great, however I've noticed that the preview frame does not respect the corner radius of the cells.

Here's my previewing function:

func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    let viewController = storyboard?.instantiateViewControllerWithIdentifier("scholarDetailViewController") as? ScholarDetailViewController
    let cellPosition = self.scholarsCollectionView.convertPoint(location, fromView: self.view)
    let cellIndex = self.scholarsCollectionView.indexPathForItemAtPoint(cellPosition)

    guard let previewViewController = viewController, indexPath = cellIndex, cell = self.scholarsCollectionView.cellForItemAtIndexPath(indexPath) else {
        return nil
    }

    let scholar = self.searchBarActive ? self.searchResults[indexPath.item] as! Scholar : self.currentScholars[indexPath.item]
    previewViewController.setScholar(scholar.id)
    previewViewController.delegate = self
    previewViewController.preferredContentSize = CGSize.zero
    previewingContext.sourceRect = self.view.convertRect(cell.frame, fromView: self.scholarsCollectionView)

    return previewViewController
}

I've tried setting the corner radius of the previewingContext sourceView and playing around with masksToBounds on the cell, but nothing I've tried so far has helped.

Here's the cell setup:

override func awakeFromNib() {
    self.layer.cornerRadius = 7
}

Anyone have any suggestions?

回答1:

As I understand you correctly you want to have something like first, instead of second:

Problem is that you register notification on whole view. Something like this: registerForPreviewingWithDelegate(self, sourceView: self.view), that why your touched area know nothing about cell layer.

What you should do — register every cell personally:

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {

    let previwingController = registerForPreviewingWithDelegate(self, sourceView: cell)
    previwingControllers[cell] = previwingController
}

func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {

    if let previwingController = previwingControllers[cell] {
      unregisterForPreviewingWithContext(previwingController)
    }
}

And just change previewingContext.sourceRect = self.view.convertRect(cell.frame, fromView: self.scholarsCollectionView) to previewingContext.sourceRect = cell.bounds

P.S. Of course don't forget to remove registerForPreviewingWithDelegate on your view :)