Search code examples
iosswiftuicollectionviewphotos

Resizing an image when the cell in a UICollectionView is selected


I have a UICollectionview with an imageview in the cell.The UICollectionview loads data from photolibrary. When the user selects an image it needs to be passed to another viewcontroller (NoteDetailViewController).This is working. But the image clarity is lost when passed to the other viewcontroller. Can anyone help me, how to modify the prepareForSegue method?

the code for the same is given below

import UIKit

import Photos

private let reuseIdentifier = "PhotoCell"

class AddPhotoViewController: UIViewController , UIImagePickerControllerDelegate ,UINavigationControllerDelegate ,UICollectionViewDataSource ,UICollectionViewDelegate
{

    @IBOutlet weak var photoAlbum: UICollectionView!

    var TakenImage : UIImageView!

    var assetCollection: PHAssetCollection!
    var photosAsset: PHFetchResult!
    var assetThumbnailSize: CGSize!
    let imagePicker: UIImagePickerController! = UIImagePickerController()
    var cameraon : Bool = false

    override func viewDidLoad()
    {
        super.viewDidLoad()

        let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)

        var i = 0
        repeat
        {
            if let first_Obj:AnyObject = collection.objectAtIndex(i)
            {
                self.assetCollection = first_Obj as! PHAssetCollection
            }
            i++
        }while( i < collection.count)



        // Do any additional setup after loading the view.
    }

    @IBAction func takePhoto(sender: AnyObject) {
        if (UIImagePickerController.isSourceTypeAvailable(.Camera)) {
            if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
                imagePicker.allowsEditing = false
                imagePicker.sourceType = .Camera
                imagePicker.cameraCaptureMode = .Photo
                presentViewController(imagePicker, animated: true, completion: {})
                cameraon = true
            } else {
                print("Rear camera doesn't exist")
            }
        } else {
            print("Camera inaccessable")
        }

    }
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
        TakenImage.image  = image
        if (cameraon)
        {
            let imageData = UIImageJPEGRepresentation(TakenImage.image!, 0.6)
            let compressedJPGImage = UIImage(data: imageData!)
            UIImageWriteToSavedPhotosAlbum(compressedJPGImage!, nil, nil, nil)

        }
        self.dismissViewControllerAnimated(true, completion: nil)
    }


    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        print("User canceled image")
        dismissViewControllerAnimated(true, completion: {
            // Anything you want to happen when the user selects cancel
        })
    }


    override func viewWillAppear(animated: Bool)
    {
        if let layout = self.photoAlbum!.collectionViewLayout as? UICollectionViewFlowLayout{
            let cellSize = layout.itemSize

            self.assetThumbnailSize = CGSizeMake(cellSize.width, cellSize.height)
        }

        //fetch the photos from collection
        self.photosAsset = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)

        self.photoAlbum!.reloadData()


    }

    // MARK: UICollectionViewDelegate

    /*
    // Uncomment this method to specify if the specified item should be selected
    override func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
    }
    */


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {
        if (segue.identifier == "savePhoto")
        {
            if let controller : NoteDetailViewController = segue.destinationViewController as? NoteDetailViewController
            {
                controller.imageView.image = TakenImage.image
            }
        }
        if (segue.identifier == "saveSelected")
        {
            if let controller:NoteDetailViewController = segue.destinationViewController as? NoteDetailViewController
            {
                if let cell = sender as? PhotoAlbumCollectionViewCell
                {
                        let imageToPass = cell.imageView.image

                        controller.someImage = imageToPass

                }
            }
        }
    }


    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
    {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        // #warning Incomplete implementation, return the number of items
        var count: Int = 0

        if(self.photosAsset != nil){
            count = self.photosAsset.count
        }
        print("\(self.photosAsset.count)")
        return count
    }
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell: PhotoAlbumCollectionViewCell = photoAlbum.dequeueReusableCellWithReuseIdentifier("PhotoCell", forIndexPath: indexPath) as! PhotoAlbumCollectionViewCell

        //Modify the cell
        let asset: PHAsset = self.photosAsset[indexPath.item] as! PHAsset

        PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: self.assetThumbnailSize, contentMode: .AspectFill, options: nil, resultHandler: {(result, info)in
            if let image = result {
                cell.setThumbnailImage(image)
            }
        })

        return cell
    }



    func collectionView(collectinView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 4
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1
    }

    func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return false
    }

    func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) -> Bool {
        return false
    }

    func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) {

        self.dismissViewControllerAnimated(false, completion: nil)

    }

} 

Solution

  • First you request the targetSize to be the one of thumbnail in cellForRowAtIndexPath. Now inside prepareForSegue you need to ask the PHImageManager for the asset again but now using a bigger TargetSize, one that fits your needs You can ask the collectionView for the indexPathsForSelectedItems() which you can use to know which asset the user selected

    if (segue.identifier == "saveSelected")
        {
            if let controller:NoteDetailViewController = segue.destinationViewController as? NoteDetailViewController
            {
                if let cell = sender as? PhotoAlbumCollectionViewCell
                {
                    let asset: PHAsset = self.photosAsset[indexPath.item] as! PHAsset
    
                    PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: controller.view.size, contentMode: .AspectFill, options: nil, resultHandler: {(result, info)in
                        if let image = result {
                            cell.setThumbnailImage(image)
                        }
                    })
    
                        controller.someImage = imageToPass
    
                }
            }
        }