2016-02-03 16 views
10

Zmiana kolejności pracuje w iOS9 kiedy dodać to do mojego UICollectionViewController podklasyUICollectionViewController zmiana kolejności nie działa, gdy osadzony w widoku kontenera

override func collectionView(collectionView: UICollectionView, 
     moveItemAtIndexPath sourceIndexPath: NSIndexPath, 
      toIndexPath destinationIndexPath: NSIndexPath) 

To nie działa, gdy ten UICollectionViewController podklasą jest osadzony w widoku kontenera.

Zrobiłem prezentację problemu here

Wszelkie pomysły, dlaczego i jak to naprawić?

+0

Updated Przykład z roztworu przez @Scooter [tutaj] (https://github.com/jameszaghini/UICollectionViewController-reordering-problem/tree/fixed) –

Odpowiedz

13

Problem polega na tym, że umieszczasz UICollectionView wewnątrz UIContainerView, który rezyduje wewnątrz kontrolera UIViewController. Wymaga to kilku dodatkowych kroków, aby UICollectionView działał zgodnie z oczekiwaniami.

Dodaj poniższe linie do viewDidLoad w CollectionViewController:

self.collectionView!.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")) 

Następnie dodać następującą funkcję do CollectionViewController:

func handleLongGesture(gesture: UILongPressGestureRecognizer) 
    { 

    switch(gesture.state) 
    { 

    case UIGestureRecognizerState.Began: 
     guard let selectedIndexPath = self.collectionView!.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else 
     { 
      break 
     } 
     collectionView!.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath) 
    case UIGestureRecognizerState.Changed: 
     collectionView!.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!)) 
    case UIGestureRecognizerState.Ended: 
     collectionView!.endInteractiveMovement() 
    default: 
     collectionView!.cancelInteractiveMovement() 
    } 
} 

Wreszcie po prostu upewnij się, aby zaliczyć, aby zapewnić sobie poradzić DataSource poprawnie:

override func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath,toIndexPath destinationIndexPath: NSIndexPath) { 
    // Swap the values of the source and destination 
} 

Sprawdź to link, aby uzyskać więcej informacji na ten temat.

Mam nadzieję, że to pomogło.

9

Odpowiedź skutera jest już w toku! Oto Swift w wersji 3 składnia:

import UIKit 

class ViewController: UIViewController 
{ 
    // MARK: - IBOutlets 
    @IBOutlet weak var uiCollectionView: UICollectionView! 

    // MARK: - Lifecycle 
    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongGesture)) 
     self.uiCollectionView.addGestureRecognizer(longPressGesture) 
    } 


    // MARK: - Gesture recogniser 
    @objc func handleLongGesture(gesture: UILongPressGestureRecognizer) 
    { 
     switch(gesture.state) 
     { 

     case .began: 
      guard let selectedIndexPath = self.uiCollectionView.indexPathForItem(at: gesture.location(in: self.uiCollectionView)) else 
      { 
       break 
      } 

      self.uiCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath) 

     case .changed: 
      self.uiCollectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!)) 

     case .ended: 
      self.uiCollectionView.endInteractiveMovement() 

     default: 
      self.uiCollectionView.cancelInteractiveMovement() 
     } 
    } 
} 


// MARK: - UICollectionViewDataSource 
extension ViewController: UICollectionViewDataSource 
{ 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    { 
     // TODO: Link to your data model 
     return 20 
    } 


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    { 
     // TODO: Link to your data model 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) 
     return cell 
    } 


    func collectionView(_ collectionView: UICollectionView, 
         moveItemAt sourceIndexPath: IndexPath, 
         to destinationIndexPath: IndexPath) 
    { 
     // TODO: Update your data model to reflect the change 
    } 
} 


// MARK: - UICollectionViewDelegate 
extension ViewController: UICollectionViewDelegate 
{ 
    // TODO: Add any UICollectionViewDelegate here if needed. 
} 

Należy pamiętać, że kod ten nie uwzględnia w dotyku lokalizacji offsetowej - więc komórka „skok” być skupione pod palcem po rozpoczęciu przeciągania. Jeśli chcesz temu zapobiec, musisz zdefiniować w swojej właściwości UIViewController a CGPoint (o nazwie initialGestureLocationInCell w poniższym kodzie). A następnie zastąpić w początkowym przykład z tym:

[...] 
     case .began: 
     guard let selectedIndexPath = self.uiCollectionView.indexPathForItem(at: gesture.location(in: self.uiCollectionView)) else 
     { 
      break 
     } 

     let selectedCell = self.uiCollectionView.cellForItem(at: selectedIndexPath)! 
     let gestureLocationInCell_RelativeToOrigin = gesture.location(in: selectedCell) 
     let gestureLocationInCell_RelativeToCentre = CGPoint(x: gestureLocationInCell_RelativeToOrigin.x - selectedCell.frame.size.width/2, 
                  y: gestureLocationInCell_RelativeToOrigin.y - selectedCell.frame.size.height/2) 

     self.initialGestureLocationInCell = gestureLocationInCell_RelativeToCentre 
     self.uiCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath) 

    case .changed: 
     let gestureLocationInCollectionView = gesture.location(in: gesture.view!) 
     let targetPosition = CGPoint(x: gestureLocationInCollectionView.x - self.initialGestureLocationInCell.x, 
            y: gestureLocationInCollectionView.y - self.initialGestureLocationInCell.y) 

     self.uiCollectionView.updateInteractiveMovementTargetPosition(targetPosition) 
[...] 
+1

Dzięki za aktualizacja do Swift 3.0! – Scooter

+1

Druga część naprawdę przydatna! Dzięki. – Nico

+0

Dziękuję bardzo za porady dotyczące przesunięcia lokalizacji dotykowej. – Storix