Resizing an image when the cell in a UICollectionView is selected - ios

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

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

Related

Questions about removing ios photo asset in Swift

This source code is a photo app like the iPhone's photo app.
When you launch the app, each Asset that is a CollectionViewCell is shown.
What I would like to ask is the ability to select and delete an image asset. If you look at the iPhone photo app, you can press the select button to select photos and delete and share selected photos. You can choose as many photos as you want rather than just one. I have implemented #IBAction selectButtonPressed.
class PhotoCollectionViewController: UICollectionViewController {
#IBOutlet weak var sortButton: UIBarButtonItem!
#IBOutlet weak var selectButton: UIBarButtonItem!
#IBOutlet weak var actionButton: UIBarButtonItem!
#IBOutlet weak var trashButton: UIBarButtonItem!
// MARK:- Properties
var fetchResult: PHFetchResult<PHAsset>? {
didSet {
OperationQueue.main.addOperation {
self.collectionView?.reloadSections(IndexSet(0...0))
}
}
}
var assetCollection: PHAssetCollection?
// MARK:- Privates
private let cellReuseIdentifier: String = "photoCell"
private lazy var cachingImageManager: PHCachingImageManager = {
return PHCachingImageManager()
}()
// MARK:- Life Cycle
deinit {
PHPhotoLibrary.shared().unregisterChangeObserver(self)
}
#IBAction func sortButtonPressed(_ sender: UIBarButtonItem) {
let fetchOptions: PHFetchOptions = PHFetchOptions()
if (self.sortButton.title == "In the past") {
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "modificationDate",
ascending: false)]
self.fetchResult = PHAsset.fetchAssets(in: assetCollection!, options: fetchOptions )
self.sortButton.title = "The latest"
} else if (self.sortButton.title == "The latest") {
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",
ascending: true)]
self.fetchResult = PHAsset.fetchAssets(in: assetCollection!, options: fetchOptions )
self.sortButton.title = "In the past"
}
}
#IBAction func seletButtonPressed(_ sender: Any) {
if (self.sortButton.isEnabled == true) {
self.sortButton.isEnabled = false
self.actionButton.isEnabled = true
self.trashButton.isEnabled = true
} else if (self.sortButton.isEnabled == false) {
self.sortButton.isEnabled = true
self.actionButton.isEnabled = false
self.trashButton.isEnabled = false
}
PHPhotoLibrary.shared().performChanges({
//Delete Photo
PHAssetChangeRequest.deleteAssets(self.fetchResult!)
},
completionHandler: {(success, error)in
NSLog("\nDeleted Image -> %#", (success ? "Success":"Error!"))
if(success){
}else{
print("Error: \(error)")
}
})
}
}
extension PhotoCollectionViewController {
private func configureCell(_ cell: PhotoCollectionViewCell,
collectionView: UICollectionView,
indexPath: IndexPath) {
guard let asset: PHAsset = self.fetchResult?.object(at: indexPath.item) else { return }
let manager: PHCachingImageManager = self.cachingImageManager
let handler: (UIImage?, [AnyHashable:Any]?) -> Void = { image, _ in
let cellAtIndex: UICollectionViewCell? = collectionView.cellForItem(at: indexPath)
guard let cell: PhotoCollectionViewCell = cellAtIndex as? PhotoCollectionViewCell
else { return }
cell.imageView.image = image
}
manager.requestImage(for: asset,
targetSize: CGSize(width: 100, height: 100),
contentMode: PHImageContentMode.aspectFill,
options: nil,
resultHandler: handler)
}
}
// MARK:- UICollectionViewDataSource
extension PhotoCollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return self.fetchResult?.count ?? 0
}
}
extension PhotoCollectionViewController {
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: PhotoCollectionViewCell
cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier,
for: indexPath) as! PhotoCollectionViewCell
return cell
}
override func collectionView(_ collectionView: UICollectionView,
willDisplay cell: UICollectionViewCell,
forItemAt indexPath: IndexPath) {
guard let cell: PhotoCollectionViewCell = cell as? PhotoCollectionViewCell else {
return
}
self.configureCell(cell, collectionView: collectionView, indexPath: indexPath)
}
}
// MARK:- UICollectionViewDelegateFlowLayout
extension PhotoCollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
guard let flowLayout: UICollectionViewFlowLayout =
self.collectionViewLayout as? UICollectionViewFlowLayout else { return CGSize.zero}
let numberOfCellsInRow: CGFloat = 4
let viewSize: CGSize = self.view.frame.size
let sectionInset: UIEdgeInsets = flowLayout.sectionInset
let interitemSpace: CGFloat = flowLayout.minimumInteritemSpacing * (numberOfCellsInRow - 1)
var itemWidth: CGFloat
itemWidth = viewSize.width - sectionInset.left - sectionInset.right - interitemSpace
itemWidth /= numberOfCellsInRow
let itemSize = CGSize(width: itemWidth, height: itemWidth)
return itemSize
}
}
extension PhotoCollectionViewController {
private func updateCollectionView(with changes: PHFetchResultChangeDetails<PHAsset>) {
guard let collectionView = self.collectionView else { return }
// 업데이트는 삭제, 삽입, 다시 불러오기, 이동 순으로 진행합니다
if let removed: IndexSet = changes.removedIndexes, removed.count > 0 {
collectionView.deleteItems(at: removed.map({
IndexPath(item: $0, section: 0)
}))
}
if let inserted: IndexSet = changes.insertedIndexes, inserted.count > 0 {
collectionView.insertItems(at: inserted.map({
IndexPath(item: $0, section: 0)
}))
}
if let changed: IndexSet = changes.changedIndexes, changed.count > 0 {
collectionView.reloadItems(at: changed.map({
IndexPath(item: $0, section: 0)
}))
}
changes.enumerateMoves { fromIndex, toIndex in
collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
to: IndexPath(item: toIndex, section: 0))
}
}
}
// MARK:- PHPhotoLibraryChangeObserver
extension PhotoCollectionViewController: PHPhotoLibraryChangeObserver {
private func resetCachedAssets() {
self.cachingImageManager.stopCachingImagesForAllAssets()
}
func photoLibraryDidChange(_ changeInstance: PHChange) {
guard let fetchResult: PHFetchResult<PHAsset> = self.fetchResult
else { return }
guard let changes: PHFetchResultChangeDetails<PHAsset> =
changeInstance.changeDetails(for: fetchResult)
else { return }
DispatchQueue.main.sync {
self.resetCachedAssets()
self.fetchResult = changes.fetchResultAfterChanges
if changes.hasIncrementalChanges {
self.updateCollectionView(with: changes)
} else {
self.collectionView?.reloadSections(IndexSet(0...0))
}
}
}
}
extension PhotoCollectionViewController {
// MARK:- Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
PHPhotoLibrary.shared().register(self)
self.sortButton.title = "In the past"
self.actionButton.isEnabled = false
self.trashButton.isEnabled = false
}
}
AssetCollection can be selected by clicking the select barButtonItem in the upper right corner of the screen, and I want to delete or share selected pictures.
You can perfore delete action on phAsset as below:
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
//Delete Photo
PHAssetChangeRequest.deleteAssets(delShotsAsset)
},
completionHandler: {(success, error)in
NSLog("\nDeleted Image -> %#", (success ? "Success":"Error!"))
if(success){
}else{
println("Error: \(error)")
}
})

Building SQLite Database with Photos

I am aiming to display images collected by the user from a DetailViewController, in a UICollectionView controller. I want to use a SQLite Database, but am unsure how to start it, seeing as I already have most of my app built and established. Below see my DetailViewController (where the images are collection and displayed), ImageStore.swift (Where the images are currently being stored), and the UICollectionView controller.
ImageStore.swift:
class ImageStore: NSObject {
let cache = NSCache()
func setImage(image: UIImage, forKey key: String) {
cache.setObject(image, forKey: key)
let imageURL = imageURLForKey(key)
if let data = UIImageJPEGRepresentation(image, 0.5) {
data.writeToURL(imageURL, atomically: true)
}
}
func imageForKey(key: String) -> UIImage? {
if let existingImage = cache.objectForKey(key) as? UIImage {
return existingImage
}
let imageURL = imageURLForKey(key)
guard let imageFromDisk = UIImage(contentsOfFile: imageURL.path!) else {
return nil
}
cache.setObject(imageFromDisk, forKey: key)
return imageFromDisk
}
func deleteImageForKey(key: String) {
cache.removeObjectForKey(key)
let imageURL = imageURLForKey(key)
do {
try NSFileManager.defaultManager().removeItemAtURL(imageURL)
}
catch let deleteError {
print("Error removing the image from disk: \(deleteError)")
}
}
func imageURLForKey(key: String) -> NSURL {
let documentsDirectories = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
let documentDirectory = documentsDirectories.first!
return documentDirectory.URLByAppendingPathComponent(key)
}
DetailViewController:
var imageStore: ImageStore!
#IBAction func takePicture(sender: UIBarButtonItem) {
let imagePicker = UIImagePickerController()
if UIImagePickerController.isSourceTypeAvailable(.Camera) {
imagePicker.sourceType = .Camera
} else {
imagePicker.sourceType = .PhotoLibrary
}
imagePicker.delegate = self
presentViewController(imagePicker, animated: true, completion: nil)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
imageStore.setImage(image, forKey: item.itemKey)
imageView.image = image
dismissViewControllerAnimated(true, completion: nil)
}
UICollectionView:
class PhotosViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: 100, height: 100)
let myCollectionView:UICollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
myCollectionView.dataSource = self
myCollectionView.delegate = self
myCollectionView.registerClass(RDCellCollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
myCollectionView.backgroundColor = UIColor.whiteColor()
self.view.addSubview(myCollectionView)
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count
}
var images: [UIImage] = [
]
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let myCell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! RDCellCollectionViewCell
myCell.imageView.image = images[indexPath.item]
return myCell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
print("User tapped on item \(indexPath.row)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

Photos framework.How to get date and location fromt the selected image

I have a collectionview which loads from the library. The selected image is displayed in another viewcontroller. I want to fetch the exif data from the image(location and date). How should I modify the code to do this?
the code for the page listing images is shown below:
import UIKit
import Photos
import MobileCoreServices
private let reuseIdentifier = "PhotoCell"
class AddPhotoViewController: UIViewController , UIImagePickerControllerDelegate ,UINavigationControllerDelegate ,UICollectionViewDataSource ,UICollectionViewDelegate{
#IBOutlet weak var photoAlbum: UICollectionView!
var TakenImage : UIImage?
var newMedia: Bool?
var selectedImage : UIImage!
var pickedImage : UIImage!
var assetCollection: PHAssetCollection!
var photosAsset: PHFetchResult!
var assetThumbnailSize: CGSize!
let imagePicker: UIImagePickerController! = UIImagePickerController()
var cameraon : Bool = false
var index : [NSIndexPath]!
var note : String!
var tags = ""
var noteAlreadyEntered = false
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationController?.navigationBar.barTintColor = UIColor.grayColor()
let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumUserLibrary, options: nil)
var i = 0
repeat
{
if (collection.count > 0)
{
if let first_Obj:AnyObject = collection.objectAtIndex(i)
{
self.assetCollection = first_Obj as! PHAssetCollection
}
i += 1
}
}while( i < collection.count)
// Do any additional setup after loading the view.
}
func takePhoto(sender : UIButton)
{
if (UIImagePickerController.isSourceTypeAvailable(.Camera))
{
if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
imagePicker.allowsEditing = false
imagePicker.sourceType = .Camera
imagePicker.cameraCaptureMode = .Photo
presentViewController(imagePicker, animated: true, completion: {})
} else {
print("Rear camera doesn't exist Application cannot access the camera.")
}
} else {
print("Camera inaccessable Application cannot access the camera.")
}
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
print("Got an image")
if let pickedImage:UIImage = (info[UIImagePickerControllerOriginalImage]) as? UIImage {
let selectorToCall = Selector("imageWasSavedSuccessfully:didFinishSavingWithError:context:")
UIImageWriteToSavedPhotosAlbum(pickedImage, self, selectorToCall, nil)
TakenImage = pickedImage
}
imagePicker.dismissViewControllerAnimated(true, completion: {
// Anything you want to happen when the user saves an image
})
}
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 == "saveSelected")
{
let cell = sender as! PhotoAlbumCollectionViewCell
let indexPath = photoAlbum.indexPathForCell(cell)
let destVC = segue.destinationViewController as! NoteDetailViewController
destVC.asset = self.photosAsset[indexPath!.item] as! PHAsset
destVC.flag = true
if(noteAlreadyEntered == true)
{
destVC.content = note
if (self.tags != "")
{
destVC.tagsTextField.text = self.tags
}
}
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
if (indexPath.row == 0)
{
let controller = self.storyboard!.instantiateViewControllerWithIdentifier("NoteDetailViewController") as! NoteDetailViewController
controller.takinPhoto = true
if(noteAlreadyEntered == true)
{
controller.content = note
controller.imageView.image = TakenImage
controller.tagsTextField.text = self.tags
}
else
{
controller.imageView2.image = TakenImage
controller.tagsTextField.text = self.tags
}
self.navigationController!.pushViewController(controller, animated: true)
}
}
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
if (indexPath.item == 0)
{
let btn = UIButton(frame: cell.contentView.bounds) //Set your frame that you want
// btn.setBackgroundImage(UIImage(named: "Compact Camera Filled-50.png"), forState: .Normal)
btn.setImage(UIImage(named: "Compact Camera Filled-50.png"), forState: .Normal)
btn.addTarget(self, action: "takePhoto:", forControlEvents: UIControlEvents.TouchUpInside)
cell.contentView.addSubview(btn)
}
else
{
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)
}
}
A photo is a PHAsset. PHAsset gives you properties representing its metadata.
If you want the raw EXIF metadata you'll have to pass through something like CIImage.

Display bigger Image in next view Controller from CollectionView

I used SDWEBIMAGE to display images in a UICollectionView from an API. Now, When the user taps on the image in a collectionview, i want to open the image in the next viewcontroller. I am able to display the title in the next View, but couldn't display the image because i want not able to assign it at UIImage. I am using swift.
can anyone please suggest me a way on how to do it.
import UIKit
import SDWebImage
private let reuseIdentifier = "Celll"
var titles = [String]()
var imagecollection = [String]()
class CollectionViewController: UICollectionViewController,
UICollectionViewDelegateFlowLayout {
let sectioninserts = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
var titles = [String]()
var imagecollection = [String]()
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "https://api.myjson.com/bins/537mf")!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
if error != nil {
print("error")
}else {
if let urlcontent = data {
do {
let jsoncontent = try NSJSONSerialization.JSONObjectWithData(urlcontent, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
// print(jsoncontent)
if jsoncontent.count > 0 {
let items = jsoncontent["items"] as! NSArray
for item in items as! [[String:String]]{
self.imagecollection.append(item["media"]!)
print(self.imagecollection)
self.titles.append(item["title"]!)
print(self.titles)
}
dispatch_async(dispatch_get_main_queue(), {
self.collectionView?.reloadData()
})
}
} catch {}
}
}
}
task.resume()
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return imagecollection.count
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionViewCell
cell.titleee.text = self.titles[indexPath.row]
let imagestring = imagecollection[indexPath.row]
let imageurl = NSURL(string: imagestring)
cell.disp.sd_setImageWithURL(imageurl, placeholderImage: UIImage(named: "loading.gif"), options: SDWebImageOptions.ProgressiveDownload, completed: nil)
return cell
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
return CGSize(width: 170, height: 300)
}
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return sectioninserts
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detail" {
let cell = sender as! CollectionViewCell
let indexPath = collectionView?.indexPathForCell(cell)
let vc = segue.destinationViewController as! DetailViewController
vc.label = self.titles[indexPath!.row]
enter code here**
Step-1
on that DetailViewController create the another one String like MediaStr
class DetailViewController: UIViewController {
var MediaStr: String
var label: String
override func viewDidLoad() {
super.viewDidLoad()
print (MediaStr)
}
}
Step-2
on your first VC Call Direclt like
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detail" {
let cell = sender as! CollectionViewCell
let indexPath = collectionView?.indexPathForCell(cell)
let vc = segue.destinationViewController as! DetailViewController
vc.label = self.titles[indexPath!.row]
// add the folloing line
vc.MediaStr = self. imagecollection[indexPath!.row]
}
Step-3
for image loading purpose
import SDWebImage
class DetailViewController: UIViewController {
var MediaStr: String
var label: String
override func viewDidLoad() {
super.viewDidLoad()
print (MediaStr)
if let imagestring = MediaStr
{
yourImageViewName_setImageWithURL(NSURL(string: imagestring), placeholderImage: UIImage(named: "loading.gif"), options: SDWebImageOptions.ProgressiveDownload, completed: nil)
}
}
}

UICollectionview which loads photos from library.How to pass Image to another viewcontroller

I have a collectionview which loads images from photo library using photos framework.I have added a segue named saveSelected for the purpose of passing the selected image to another viewController NoteDetailViewController.How can I pass the same
My AddPhotoViewController 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 controller2 : NoteDetailViewController = segue.destinationViewController as? NoteDetailViewController
{
if let cell = photoAlbum.cel as? PhotoAlbumCollectionViewCell
{
}
}
}*/
}
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(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
}
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)
}
}
How should I modify the didSelectItemAtIndexPath and prepareForSegue to achieve this?
You have set segue with CollectionViewCell so there is no need to write any thing in your didSelectItemAtIndexPath method, Change your code like this in prepareForSegue method
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "saveSelected")
{
let cell = sender as! PhotoAlbumCollectionViewCell
let indexPath = tableView.indexPathForCell(cell)
let destVC = segue.destinationViewController as! NoteDetailViewController
destVC.asset = self.photosAsset[indexPath.item] as! PHAsset
}
}
Now create one global object with name asset in NoteDetailViewController like this
var asset: PHAsset!
Now add like below code in your viewDidLoad of NoteDetailViewController
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: self.assetThumbnailSize, contentMode: .AspectFill, options: nil, resultHandler: {(result, info)in
if let image = result {
self.imageView.image = image
}
})
}
Hope this will help you.
You can't set any imageviews or outlets before the controller is loaded, so you've to modify your segue code and the other controller to have an image that will be sent when segued.
if (segue.identifier == "savePhoto")
{
if let controller : NoteDetailViewController = segue.destinationViewController as? NoteDetailViewController
{
controller.image = TakenImage.image
}
}
then modify the segued class:
class NoteDetailViewController: UITableViewController {
var image: UIImage!
}

Resources