Home > Net >  How to Update Array Index After Drag and Drop is Called in UserDefaults in CollectionView?
How to Update Array Index After Drag and Drop is Called in UserDefaults in CollectionView?

Time:04-21

I'm Creating an demo, In this I have Drag and Drop Functionality , Drag and Drop function is working Perfectly Fine, My Concern is , when I close the app and came back to the View again, the same is Index is showing in the array, I want to Get the array as I do Drag and Drop at a index.

Here's My Code

CollectionView Methods

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return array.count
    
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
    cell.lbl.text = array[indexPath.row]
    cell.img.layer.cornerRadius = cell.img.frame.size.width / 2
    cell.lbl.layer.cornerRadius = cell.lbl.frame.size.width / 2
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: (collectionView.frame.size.width / 2) - 20, height: 200)
}

func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
    return true
}

func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    let item = array.remove(at: sourceIndexPath.item)
    defaults.removeObject(forKey: "data")
    array.insert(item, at: destinationIndexPath.item)
    defaults.set(item, forKey: "data")
    defaults.synchronize()
    
    print(item )
}

View Did Load and LongPressGesture Methods

@IBOutlet weak var collectionView: UICollectionView!
var array = ["Fateh", "Parul", "Jitendra", "Javed", "Brijesh","Pandey Ji"]
let defaults = UserDefaults.standard
var longPress : UILongPressGestureRecognizer!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    if UserDefaults.standard.array(forKey: "data") == nil {
         // userDefault has a value
   
        defaults.set(array, forKey: "data")
        
    } else  {
        let newData = defaults.object(forKey: "data")
        array = newData as! [String]
    }
    
    
    collectionView.delegate = self
    collectionView.dataSource = self
    longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongGesture(gesture:)))
    collectionView.addGestureRecognizer(longPress)
}

@objc func handleLongGesture(gesture : UILongPressGestureRecognizer){
    switch gesture.state {
    case .began:
        guard let selectedIndex = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {
            break
        }
        collectionView.beginInteractiveMovementForItem(at: selectedIndex)
    case .changed:
        collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view))
        
    case .ended:
        collectionView.endInteractiveMovement()
        defaults.synchronize()
    @unknown default:
        collectionView.cancelInteractiveMovement()
    }
}

CodePudding user response:

In viewDidLoad, if there is no data already saved in UserDefaults, you are doing this:

defaults.set(array, forKey: "data")

You're setting the array as the data.

In moveItemAt, you're doing this:

defaults.set(item, forKey: "data")

You're setting only an individual item as the data, when you should be setting the updated array as the data.

As a side note, there is no need for defaults.synchronize() ... from Apple's docs:

synchronize()

Waits for any pending asynchronous updates to the defaults database and returns; this method is unnecessary and shouldn't be used.

  • Related