2016-08-06 10 views
21

Ich versuche, die Swipe zu löschen Funktion wie in der Mail-Tabellenansicht zu replizieren. Nur dieses Mal muss ich es auf einer CollectionView aufbauen, aber ich habe eine harte Zeit. Es ist eine horizontale Scroll-Liste mit einem Wischen nach oben zum Löschen. Ich habe bereits die Wischfunktion, aber es ist schwer herauszufinden, wie ich den Swipe zum Löschen/Antippen einrichten muss, um Funktionen zu löschen oder zu ignorieren.Swipe zum Löschen auf CollectionView

Es sieht wie folgt aus: Delete Image

Also ich bin mit dem folgenden Kollektion:

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 
} 

Meine benutzerdefinierte videocell ein Bild enthält, und darunter gibt es die Schaltfläche Löschen. Wenn Sie also das Bild nach oben streichen, erscheint die Löschtaste. Nicht sicher, ob dies der richtige Weg ist, wie man es tun:

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") 
} 
} 

Und ich verwende die folgende Logik:

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. 
    } 
} 

Aber das Problem beginnt dort. Sobald meine Zelle außerhalb der Collectview-Grenzen ist, kann ich nicht mehr darauf zugreifen. Ich möchte es noch weiter wischen, um es zu entfernen. Ich kann das nur tun, indem ich auf die Schaltfläche "Löschen" wische, aber ich möchte, dass die Bildansicht darüber auch wischbar ist. Oder wenn ich auf das Bild außerhalb der Sammlungsansicht tippe, sollte es in die Zeile zurückgleiten und es nicht löschen.

Wenn ich die Collectview-Grenzen erhöhen, kann ich dieses Problem verhindern, aber ich kann auch wischen, um außerhalb der sichtbaren Höhe der Zelle zu entfernen. Dies wird durch die tapLocation verursacht, die sich in der Sammlungsansicht befindet und einen Indexpfad erkennt. Etwas, das ich nicht will. Ich möchte das Wischen nur in einer Collectionview Zelle arbeiten.

Auch der Knopf und das Bild stören sich gegenseitig, weil ich sie nicht unterscheiden kann. Sie sind beide in der gleichen Zelle, deshalb frage ich mich, ob ich überhaupt den Lösch-Knopf in der Zelle haben sollte. Oder wo sollte ich es sonst platzieren? Ich könnte auch zwei Tasten daraus machen und die Benutzerinteraktion je nach Status deaktivieren, aber nicht sicher, wie das enden würde.

Antwort

3

Um meiner eigenen Neugier Willen habe ich versucht, eine Replikation von dem, was Sie versuchen, zu machen, und es irgendwie gut funktioniert. Es unterscheidet sich von Ihnen durch die Art und Weise, wie ich die Wischgesten eingerichtet habe, da ich keine Pan verwendet habe, aber Sie sagten, dass Sie diesen Part bereits hatten und nicht zu viel Zeit damit verbracht haben.Pan ist offensichtlich die solidere Lösung, um es interaktiv zu machen, aber es dauert ein wenig länger, um zu berechnen, aber die Wirkung und Handhabung davon sollte sich nicht sehr von meinem Beispiel unterscheiden.

Um das Problem nicht in der Lage zu lösen ist außerhalb der Zelle zu streichen ich, wenn der Punkt in der Swiped rect war beschlossen zu prüfen, die sich wie die doppelte Höhe des nicht Swiped rect ist:

  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!]) 

      } 

Ich habe eine Demonstration mit Kommentaren erstellt: https://github.com/imbue11235/swipeToDeleteCell

Ich hoffe, es hilft Ihnen auf jeden Fall!

+0

Ich bin sicherlich an Ihrer Lösung interessiert. Könntest du eine aktualisierte Version nach Github schieben, weil ich momentan nur ein leeres Projekt bekomme? – Wouter125

+0

Oh ja sicher, das ist ein Fehler, peinlich. Es ist jetzt aktualisiert! – Imbue

+0

Funktioniert wie ein Charme. War genau das, wonach ich suchte. Habe es bereits für meine Pangeschreibung neu geschrieben, aber in der Tat habe ich versucht, den Zellbereich zu vergrößern :) – Wouter125

8

Wenn Sie also möchten, dass die Gestenerkennungsfunktion die Bewegung weiter aufnimmt, wenn sie sich außerhalb ihrer Sammlungsansicht befindet, müssen Sie sie an das übergeordnete Element der Sammlungsansicht anhängen, sodass sie an den gesamten Bereich gebunden ist wischen.

Das bedeutet, dass Sie für Objekte außerhalb der Sammlungsansicht wischen, aber Sie können diese mit einer beliebigen Anzahl von Techniken leicht ignorieren.

Taste Taps löschen Um sich anzumelden, müssen Sie addTarget nennen: Aktion: forControlEvents: auf die Schaltfläche

Ich würde halten die Zelle, wie Sie es haben, mit dem Bild und der zusammen drücken. Es wird viel einfacher zu verwalten sein, und sie gehören zusammen.

Um das Bild nach oben und unten zu bewegen, würde ich mit einer Transformation oder NSLayoutConstraint suchen. Dann müssen Sie nur einen Wert anpassen, um ihn synchron mit den Wischen des Benutzers nach oben und unten zu bewegen. Kein Durcheinander mit Frames.

+0

Lassen Sie mich jede Alinea herunter laufen. Wenn ich es an die Elternansicht von, wie Sie gesagt haben, anfügen, werde ich überall wischen. Das Problem ist, sobald meine Zelle außerhalb meiner Collection-Ansicht ist, wird mein Indexpfad in der Löschzellen-Funktion zu Null und ich kann die Zelle nicht mehr ziehen. Die Vergrößerung meiner CollectionView-Größe wird es möglich machen, aber es wird Benutzern auch ermöglichen, Zellen herumzuziehen, wenn sie nicht einmal das Bild selbst berühren. Löschen Aktion kann leicht behoben werden. Das einzige Problem ist, dass die Bildansicht eine andere Aktion als die Schaltfläche zum Löschen hat. Wie kombiniert man diese beiden Aktionen, wenn beide sichtbar sind? – Wouter125

+0

Ich bin mir nicht sicher, ich würde mir vorstellen, dass das Deaktivieren der Sammlungsansicht von Clips in Grenzen die Transformation der Bildansicht außerhalb der Eltern ermöglichen würde. 'myCollectionView.clipsToBounds = false' – Michael

+0

Nein, das wird nicht funktionieren, weil eine Ansicht nur" touch down "-Ereignisse an Unteransichten weitergibt (Zellen in der Sammlungsansicht), wenn sie innerhalb ihrer Grenzen liegen. Das Erhöhen der Grenzen wird funktionieren, aber es ist nicht das, was ich will. Irgendwelche anderen Vorschläge? Ich könnte die pointInside-Methode überschreiben, aber das ist etwas, was ich nicht will, weil ich denke, dass es meinen Indexpfad nicht zurückgibt. – Wouter125

Verwandte Themen