简体   繁体   English

在同一视图控制器中的多个集合视图或表视图上实现3D触摸

[英]Implement 3D touch on multiple collection views or table views in the same view controller

I would like to have 3D touch on both of the collection views of my app(Only the "Peek" functionality). 我想对我的应用程序的两个集合视图进行3D触摸(仅“ Peek”功能)。 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? 如何将它们分开,以便仅对我选择的collectionview单元专门发生一次?

Here is how I am implementing the 3D touch functionality: 这是我实现3D触摸功能的方式:

I put this in VC's viewDidAppear because it wasn't working in viewDidLoad for some reason: 我将其放在VC的viewDidAppear中,因为某些原因,它在viewDidLoad中不起作用:

  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: 这也是我在VC中包含两个collectionview的内容:

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: 这是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 发生的事情的gif

This is what I did in my project. 这就是我在项目中所做的。

I have a scrollView on the top of the viewController and a tableView on the bottom. 我在viewController的顶部有一个scrollView,在底部的有tableView。 And I would like two of them to adopt the peek and pop. 我希望其中两个人采用peek和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. 首先,您需要将UIViewControllerPreviewingDelegate添加到要实现peek和pop函数的viewController中。

Second, register the container view (usually is self.view) by calling 其次,通过调用注册容器视图(通常是self.view)

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 第三,将视图坐标系的CGPoint转换为您希望在PreviewingContext委托中具有窥视和弹出功能的任何视图

func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?

For example: 例如:

a. 一种。 Convert CGPoint on the self.view to the point inside tableView 将self.view上的CGPoint转换为tableView内的点

let tableViewPoint = tableView.convertPoint(location, fromView: view)

b. 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. 完成这一点后,您可以确认tableViewPoint是否在tableView内,从tableViewPoint获取tableViewCell并对其进行处理。

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. 然后对滚动视图执行完全相同的操作,那么您将可以在同一个viewController中同时滚动和滚动查看view和tableView。

Last implement the second delegate for pop 最后实现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. 希望它也会对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM