2016-08-06 10 views
21

Я пытаюсь реплицировать салфетки для удаления функции, как в почтовом представлении таблицы. Только на этот раз мне нужно собрать его в виде коллекции, но мне немного тяжело. Это горизонтальный список прокрутки с удалением, чтобы удалить. У меня уже есть прокрутка вверх, но мне сложно определить, как мне нужно настроить салфетки, чтобы удалить/коснуться, чтобы удалить или проигнорировать функциональность.Проведите по удалению в CollectionView

Это выглядит следующим образом: Delete Image

Поэтому я использую следующую CollectionView:

func buildCollectionView() { 
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
    layout.scrollDirection = .horizontal 
    layout.minimumInteritemSpacing = 0; 
    layout.minimumLineSpacing = 4; 

    collectionView = UICollectionView(frame: CGRect(x: 0, y: screenSize.midY - 120, width: screenSize.width, height: 180), collectionViewLayout: layout) 

    collectionView.dataSource = self 
    collectionView.delegate = self 
    collectionView.register(VideoCell.self, forCellWithReuseIdentifier: "videoCell") 
    collectionView.showsHorizontalScrollIndicator = false 
    collectionView.showsVerticalScrollIndicator = false 
    collectionView.contentInset = UIEdgeInsetsMake(0, 20, 0, 30) 
    collectionView.backgroundColor = UIColor.white() 
    collectionView.alpha = 0.0 


    //can swipe cells outside collectionview region 
    collectionView.layer.masksToBounds = false 


    swipeUpRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.deleteCell)) 
    swipeUpRecognizer.delegate = self 

    collectionView.addGestureRecognizer(swipeUpRecognizer) 
    collectionView.isUserInteractionEnabled = true 
} 

Мой заказ videocell содержит одно изображение и ниже есть кнопка удаления. Поэтому, если вы пролистаете изображение, появляется кнопка удаления. Не уверен, если это правильный способ, как это сделать:

class VideoCell : UICollectionViewCell { 
var deleteView: UIButton! 
var imageView: UIImageView! 

override init(frame: CGRect) { 
    super.init(frame: frame) 

    deleteView = UIButton(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)) 
    deleteView.contentMode = UIViewContentMode.scaleAspectFit 
    contentView.addSubview(deleteView) 

    imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)) 
    imageView.contentMode = UIViewContentMode.scaleAspectFit 
    contentView.addSubview(imageView) 


} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 
} 

И я использую следующую логику:

func deleteCell(sender: UIPanGestureRecognizer) { 
    let tapLocation = sender.location(in: self.collectionView) 
    let indexPath = self.collectionView.indexPathForItem(at: tapLocation) 

    if velocity.y < 0 { 
     //detect if there is a swipe up and detect it's distance. If the distance is far enough we snap the cells Imageview to the top otherwise we drop it back down. This works fine already. 
    } 
} 

Но проблема начинается там. Как только моя ячейка находится за пределами границ коллекции, я больше не могу ее получить. Я все еще хочу провести его дальше, чтобы удалить его. Я могу сделать это только, щелкнув по кнопке удаления, но я хочу, чтобы Imageview над ним также был прокручиваем. Или, если я коснусь изображения вне коллекции, он должен вернуться в строку и не удалить его.

Если я увеличиваю границы коллекции, я могу предотвратить эту проблему, но я также могу прокрутить, чтобы удалить внешнюю видимую высоту ячейки. Это вызвано ссылкой tapLocation, которая находится внутри коллекции и обнаруживает indexPath. Что-то, чего я не хочу. Я хочу, чтобы проведите по экрану только для работы с ячейкой коллекции.

Также кнопка и изображение мешают друг другу, потому что я не могу их отличить. Они оба находятся в одной и той же ячейке, поэтому мне интересно, есть ли у меня кнопка удаления в ячейке вообще. Или где я должен разместить его иначе? Я мог бы также сделать из него две кнопки и отключить взаимодействие пользователя в зависимости от состояния, но не уверен, как это закончится.

ответ

3

Для моего собственного любопытства я попытался воспроизвести то, что вы пытаетесь сделать, и заставить его работать как-то хорошо. Он отличается от вашего в том, как я настраиваю жесты салфетки, поскольку я не использовал панорамирование, но вы сказали, что у вас уже есть эта часть, и не тратите на нее слишком много времени.Пан, очевидно, является более надежным решением, чтобы сделать его интерактивным, но занимает немного больше времени для расчета, но эффект и обработка его не должны сильно отличаться от моего примера.

Чтобы решить эту проблему, не будучи в состоянии ударить вне клетки, я решил проверить, если точка была в прокатывается прямоугольнику, который в два раза превышает высоту, не прокатывается прямоугольнику, как это:

  let cellFrame = activeCell.frame 
      let rect = CGRectMake(cellFrame.origin.x, cellFrame.origin.y - cellFrame.height, cellFrame.width, cellFrame.height*2) 
      if CGRectContainsPoint(rect, point) { 
       // If swipe point is in the cell delete it 

       let indexPath = myView.indexPathForCell(activeCell) 
       cats.removeAtIndex(indexPath!.row) 
       myView.deleteItemsAtIndexPaths([indexPath!]) 

      } 

Я создал демонстрацию с комментариями: https://github.com/imbue11235/swipeToDeleteCell

Надеюсь, вам это поможет!

+0

Я, конечно, заинтересован в вашем решении. Не могли бы вы обновить версию до github, потому что в настоящее время я получаю пустой проект! – Wouter125

+0

О, да, конечно, это ошибка, смущающая. Он обновлен сейчас! – Imbue

+0

Работает как очарование. Именно то, что я искал. Уже переписал его для моего pangesture, но я действительно искал, как увеличить площадь ячеек :) – Wouter125

8

Итак, если вы хотите, чтобы распознаватель жестов распознавания продолжал записывать движение, когда он находится вне своего вида коллекции, вам необходимо прикрепить его к родительскому представлению коллекции, поэтому он ограничен всей областью, где пользователь может салфетки.

Это означает, что вы получите удары для вещей вне вида коллекции, но вы можете легко игнорировать тех, кто использует любое количество методов.

Для регистрации удаления нажатий кнопок, вам необходимо позвонить addTarget: Действие: forControlEvents: на кнопку

Я бы держать клетку, как у вас есть, с изображением и кнопки вместе. Управлять будет намного легче, и они будут вместе.

Чтобы управлять перемещением изображения вверх и вниз, я бы посмотрел на использование преобразования или NSLayoutConstraint. Затем вам нужно настроить одно значение, чтобы оно перемещалось вверх и вниз в синхронизации с пользовательскими прогибами. Не вмешиваться в рамки.

+0

Позвольте мне сбежать по каждой алинеи. Если я приложу его к родительскому виду, как вы сказали, я получу везде. Проблема в том, что когда моя ячейка попадает в мою коллекцию, мой индексный путь в функции deleteecell станет нулевой, и я больше не могу перетаскивать ячейку. Увеличение моего размера коллекции позволит, но это также позволит пользователям перетаскивать ячейки, когда они даже не касаются самого изображения. Удалить действие можно легко устранить. Только проблема заключается в том, что изображение имеет другое действие, чем кнопка удаления. Как объединить эти два действия, когда они оба видны? – Wouter125

+0

Я не уверен, я бы предположил, что отключение клипов просмотра коллекции до границ позволит вам преобразовать образ за пределами своих родителей. 'myCollectionView.clipsToBounds = false' – Michael

+0

Нет, это не собирается делать трюк, потому что представление будет только пересылать события« прикосновения »к subviews (ячейки внутри коллекции), если они находятся в пределах его границ. Так что увеличение границ будет работать, но это не то, что я хочу. Любые другие предложения? Я мог бы переопределить метод pointInside, но это то, чего я не хочу, потому что я думаю, что он не вернет мой индексный путь. – Wouter125