user5899631
user5899631

Reputation:

Images duplicating when adding to Array

I am using DKImagePickerController to select multiple images, displaying them on my VC and them when I press a button they upload to Parse.

I load 7 images, but only the ones visible on the screen (Which is 4, as I am using a collectionView with a horizontal scroll) upload at the begining then if I scroll across to the end and upload again It uploads all 7 images. And if I scroll back and then forwards again the images seem to add up 7 at a time, so if I scrolled 4 times back and forth I would end up uploading 28 images when I only selected 7!!

I'm guessing it something to do with the way I add the images I have selected to the image Array which I am doing in the cellForItemAtIndexPath.

Here is my code below, if anyone has incounted this before or knows the issue you help is very much appreciated!

    @IBOutlet weak var previewOrShareButton: UIBarButtonItem!
   @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var cancelButton: UIBarButtonItem!

    var assets: [DKAsset]?

    var images = [UIImage]()

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func selectImage(sender: AnyObject) {
        let pickerController = DKImagePickerController()

        pickerController.didSelectAssets = { (assets: [DKAsset]) in
            print("didSelectAssets")
            self.assets = assets

           self.collectionView.reloadData()
        }
        pickerController.defaultSelectedAssets = self.assets
        pickerController.maxSelectableCount =  7
        pickerController.allowMultipleTypes = false

        self.presentViewController(pickerController, animated: true) {}


    }


    @IBAction func postButton(sender: AnyObject) {

        let post = PFObject(className: "Post")

        post["username"] = PFUser.currentUser()!.username

        for i in self.images.indices {
            let imageData = self.images[i].lowestQualityJPEGNSData 
            let imageFile = PFFile(name: "image.JPEG", data: imageData)

        post["imageArray\(i)"] = imageFile

        }


        post.saveInBackgroundWithBlock ({(success:Bool, error:NSError?) -> Void in
            if error  == nil {
            }})
     }

 func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return self.assets?.count ?? 0
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! BlogCollectionViewCell
        let asset = self.assets![indexPath.row]



        asset.fetchOriginalImageWithCompleteBlock { (image, info) -> Void in

           cell.image.image = image

          self.images.append(image!)
        }

        print(images)

        return cell
    }

Upvotes: 0

Views: 391

Answers (2)

Ben Sullivan
Ben Sullivan

Reputation: 2154

Anything in your cellForRow will run every time a cell is scrolled to so it's fetching too many images. Ideally add the following to your viewDidLoad unless you need to the user to download the images then add this to a button:

for object in assets {
    object.fetchOriginalImageWithCompleteBlock { (image, info) -> Void in

      self.images.append(image!)
      pickerController.reloadData()

    }
}

That will load all of the images into the array and then you can populate your cells with the images:

cell.image = images[indexPath.row]

Upvotes: 1

Rajat
Rajat

Reputation: 11127

Yes you are doing it in wrong way, as you are fetching the images in cellForItemAtIndexPath and then adding the images in array in the same method. So when you scroll your UICollectionView then images will fetched and added to the array as cellForItemAtIndexPath will called when you scroll or reload your UICollectionView.

I will make some changes in your code, hope it will help you.

@IBAction func selectImage(sender: AnyObject) {

    let pickerController = DKImagePickerController()

    pickerController.didSelectAssets = { (assets: [DKAsset]) in
        print("didSelectAssets")
        assets.fetchOriginalImageWithCompleteBlock { (image, info) -> Void in
           self.images.append(image!)
           self.collectionView.reloadData()
        }
    }
    pickerController.defaultSelectedAssets = self.assets
    pickerController.maxSelectableCount =  7
    pickerController.allowMultipleTypes = false
    self.presentViewController(pickerController, animated: true) {}
}

and then cellForItemAtIndexPath will be

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! BlogCollectionViewCell
    let asset = self.assets![indexPath.row]
    cell.image.image = image
    return cell
}

Upvotes: 1

Related Questions