Реализовать 3D Touch в нескольких видах коллекций или таблиц в одном контроллере

Мне бы хотелось, чтобы 3D-касание касалось обоих видов коллекций моего приложения (только функциональность "Peek"). Они оба содержатся в одном контроллере представления. Независимо от того, какой синтаксис я пробую, он всегда показывает изображение и текст для ячейки в первом представлении коллекции, даже если я выбираю ячейку во втором представлении коллекции. Как разделить их так, чтобы только одна произошла специально для выбранной ячейки коллекции?

Вот как я реализую функциональность 3D Touch:

Я поместил это в viewDidAppear VC, потому что по какой-то причине он не работал в viewDidLoad:

  override func viewDidAppear(animated: Bool) {

  if( traitCollection.forceTouchCapability == .Available){

    registerForPreviewingWithDelegate(self, sourceView: collectionView1)
    registerForPreviewingWithDelegate(self, sourceView: collectionView2)

}

Вот то, что я также имею в VC, в котором размещены два вида коллекций:

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
}

И вот что я имею в превью ВК:

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 о том, что происходит

1 ответ

Это то, что я сделал в своем проекте.

У меня есть scrollView в верхней части viewController и tableView в нижней части. И я хотел бы, чтобы двое из них приняли взгляд и популярность. Итак, вот что я сделал.

Во-первых, вам нужно добавить UIViewControllerPreviewingDelegate в viewController, который вы хотите реализовать в функциях peek и pop.

Во-вторых, зарегистрируйте представление контейнера (обычно это self.view), вызвав

if self.traitCollection.forceTouchCapability == .Available {
    registerForPreviewingWithDelegate(self, sourceView: view)
}

В-третьих, вы преобразуете CGPoint системы координат представления в любой вид, который вы хотели бы иметь в функциях previewingContext для функции просмотра и вставки

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

Например:

а. Конвертировать CGPoint в self.view в точку внутри tableView

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

б. Получив эту точку, вы можете подтвердить, находится ли tableViewPoint внутри tableView, получить tableViewCell из tableViewPoint и что-то с ним сделать.

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
}

И затем сделайте то же самое с представлением прокрутки, тогда вы сможете использовать функции scrollView и tableView для одного и того же viewController.

Последняя реализация второго делегата для поп

func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
    showViewController(viewControllerToCommit, sender: self)
}

У меня это работает отлично. Надеюсь, это поможет вам.

Другие вопросы по тегам