问题
I would like to have 3D touch on both of the collection views of my app(Only the "Peek" functionality). They are both contained in the same view controller. No matter what syntax I try it always shows the image and text for the a cell in the first collectionview, even if I choose a cell in the second collection view. How do I separate these so that only one happens specifically for the collectionview cell I have selected?
Here is how I am implementing the 3D touch functionality:
I put this in VC's viewDidAppear because it wasn't working in viewDidLoad for some reason:
override func viewDidAppear(animated: Bool) {
if( traitCollection.forceTouchCapability == .Available){
registerForPreviewingWithDelegate(self, sourceView: collectionView1)
registerForPreviewingWithDelegate(self, sourceView: collectionView2)
}
Here is what I also have in the VC that houses the two collectionviews:
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
guard let previewVC = storyboard?.instantiateViewControllerWithIdentifier("PreviewVC") as? PreviewViewController
else{ return nil }
guard let indexPath = collectionView1?.indexPathForItemAtPoint(location) else { return nil }
guard let indexPath2 = collectionView2.indexPathForItemAtPoint(location) else { return nil }
guard let cell1 = collectionView1?.cellForItemAtIndexPath(indexPath) else { return nil }
guard let cell2 = collectionView2.cellForItemAtIndexPath(indexPath) else { return nil}
previewVC.selectedItem = String(Gifs.row1[indexPath.row])
previewVC.selectedItem2 = String(Gifs.row2[indexPath.rown])
previewVC.preferredContentSize = CGSize(width: 245, height: 200)
previewingContext.sourceRect = cell1.frame
return previewVC
}
And here is what I have in the previewVC:
class PreviewViewController: UIViewController {
@IBOutlet weak var selectedGifImageView: UIImageView!
@IBOutlet weak var textLabel: UILabel!
var selectedItem: String?
var selectedItem2: String?
var delegate: MoveScrollViewController?
override func viewWillAppear(animated: Bool) {
textLabel.text = Gifs.gifDictionary[selectedItem]
selectedGifImageView.setGifImage(UIImage(name: selectedItem))
textLabel.text = Gifs.gifDictionary[selectedItem2]
selectedGifImageView.setGifImage(UIImage(name: selectedItem2))
}
gif of what's happening
回答1:
This is what I did in my project.
I have a scrollView on the top of the viewController and a tableView on the bottom. And I would like two of them to adopt the peek and pop. So the following is what I did.
First, you need to add UIViewControllerPreviewingDelegate to the viewController that you would like to implement the peek and pop function.
Second, register the container view (usually is self.view) by calling
if self.traitCollection.forceTouchCapability == .Available {
registerForPreviewingWithDelegate(self, sourceView: view)
}
Third, you convert the CGPoint of the view coordinate system to any view that you would like to have peek and pop feature in the previewingContext delegate
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
For example:
a. Convert CGPoint on the self.view to the point inside tableView
let tableViewPoint = tableView.convertPoint(location, fromView: view)
b. After you have this point, you can confirm if the tableViewPoint is inside the tableView, get the tableViewCell from the tableViewPoint and do something with it.
if self.tableView.pointInside(tableViewPoint, withEvent: nil) {
guard let indexPath = self.tableView.indexPathForRowAtPoint(tableViewPoint) else {
return nil
}
guard let tableViewCell = self.tableView.cellForRowAtIndexPath(indexPath) else {
return nil
}
// do something with your tableView cell here...
let yourViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("YOURVIEWCONTROLLER") as! YOURVIEWCONTROLLER
// set up the contentSize for peek
yourViewController.preferredContentSize = CGSize(width: 0.0, height: 600)
// set up the focusing rect for the tableViewCell so that it won't be blurred out.
let viewPoint = self.view.convertPoint(tableCell.frame.origin, fromView: self.tableView)
previewingContext.sourceRect = CGRect(origin: viewPoint, size: tableCell.frame.size)
return yourViewController
}
And then do the exactly the same to the scroll view, then you will be able to have peek and pop for both scrollView and tableView in the same viewController.
Last implement the second delegate for pop
func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
showViewController(viewControllerToCommit, sender: self)
}
It works for me perfectly. Hopefully it will help you out as well.
来源:https://stackoverflow.com/questions/38511133/implement-3d-touch-on-multiple-collection-views-or-table-views-in-the-same-view