How to Load the Photo Library into Uicollectionview? Swift

How to load the Photo Library into UICollectionView? Swift

I assume the reason of your problem is these lines of your code:

let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Moment, subtype: .Any, options: fetchOptions)

if let first_Obj:AnyObject = collection.firstObject{
//found the album
self.assetCollection = first_Obj as! PHAssetCollection
}

The first object of fetch result is not an album, it's a moment (a photo group). Check the documentation:

PHAssetCollectionTypeMoment.
A moment in the Photos app.
The Photos app automatically creates moments to group assets by time and location.

If you want to show photos in a first album, you just need to replace .Moment with .Album. If you want to show all the photos, you need to process all objects in PHFetchResult, not just first of them.

How to display photo library in collectionView using less memory

The problem is this line:

self.imageArray.append(image!)

Never make an array of images. Images are huge, and you'll run out of memory.

This is a collection view. You simply supply the image on demand in itemForRowAt:, and what you supply is a small version of the image (a so-called thumbnail), the smallest possible for the display size. Thus there are, at any time, only enough thumbnails to fill the visible screen; that doesn't take very much memory, plus the runtime can release the image memory when an image is scrolled off the screen.

That is what PHCachingImageManager is for. Look closely at how Apple handles this in their sample code:

https://developer.apple.com/library/archive/samplecode/UsingPhotosFramework/Listings/Shared_AssetGridViewController_swift.html

There is no array of images anywhere in that example.

How to upload image from photolibrary to specific collectionview cell when that cell is selected?

You need to remember which cell you tapped before picking image. You can save the index in collectionView(_:, didSelectItemAt:)

// instance property
private var selectedCellIndexPath: IndexPath?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

selectedCellIndexPath = indexPath
let cell: UICollectionViewCell = collectionView.cellForItem(at: indexPath)!
cell.layer.borderWidth = 4.0
cell.layer.borderColor = UIColor.blue.cgColor
cellTapped()

}

Then you need to update you data source when the image is picked and reload collection.

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

guard let selectedImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
dismiss(animated: true, completion: nil)

// let us assume that your collection relies on some array called 'images'
guard let selectedCellIndexPath = selectedCellIndexPath,
selectedCellIndexPath.item < images.count else {
return
}

images[selectedCellIndexPath.item] = images
collectionView?.reloadData()
}

how to get a photo with imagepickercontroller into the collectionView cell as thumbnail

The issue is not obvious so I had to recreate it on my machine. Actually myImage array is getting loaded twice in below functions.

  1. didFinishPickingMediaWithInfo
  2. cellForItemAt

This causes the data from collection view to get added to the myImage array.
Removing the below assignment in cellForItemAt, solves the issue.
// myImage.append(dummyImageView.image!)

How would I upload new photo into collectionView cell using Firebase?

To upload images to Firebase storage and show them in a collection view, you can use the following steps;

  1. Set up collection view with an array of URLs (or Strings) as its
    data source. You can use your custom models if required.

  2. Keep a reference to your Firebase storage and upload the image. After successful upload, get the URL for the uploaded image using the image reference.

  3. Save the url in Firebase Database(or Cloud Firestore). This is required only if you want to sync the collection view with the database and update it when new images are uploaded.

  4. Add a listener to your Firebase database reference where you have
    saved the image URLs. Update the local URLs array inside the listener and reload the collection view.

If you don't want to use Firebase database, omit steps 3 and 4, save the image URL to the array and reload the collection view right away.

I'm not adding the code for collection view setup here as it's not the objective of this answer.

let storageRef = Storage.storage().reference(withPath: "images")
let databaseRef = Database.database().reference(withPath:"images")
var images: [String] = []

override func viewDidLoad() {
super.viewDidLoad()

addDatabaseListener()
}

private func addDatabaseListener() {
databaseRef.observe(.childAdded) { (snapshot) in

guard let value = snapshot.value as? [String: Any], let url = value["url"] as? String else { return }
self.images.append(url)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
guard let image = info[UIImagePickerController.InfoKey.editedImage] as? UIImage, let data = image.jpegData(compressionQuality: 0.1) else { return }

let fileName = "\(Date.timeIntervalSinceReferenceDate).jpeg"
let newImageRef = storageRef.child(fileName)

newImageRef.putData(data, metadata: nil) { (_, error) in
if let error = error {
print("upload failed: ", error.localizedDescription)
return
}

newImageRef.downloadURL { (url, error) in
if let error = error {
print("error: ", error.localizedDescription)
return
}
self.databaseRef.childByAutoId().setValue(["url": url?.absoluteString])
}
}

}

why collection view in empty when I fetch photos from gallery in swift 3?

This is my whole code to load all images from gallery and load into collectioview. Please see this code

import UIKit
import Photos
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
let arr_img = NSMutableArray()
@IBOutlet var collview: UICollectionView!

override func viewDidLoad() {
super.viewDidLoad()
let allPhotosOptions : PHFetchOptions = PHFetchOptions.init()
allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let allPhotosResult = PHAsset.fetchAssets(with: .image, options: allPhotosOptions)
allPhotosResult.enumerateObjects({ (asset, idx, stop) in

self.arr_img.add(asset)
})

}
func getAssetThumbnail(asset: PHAsset, size: CGFloat) -> UIImage {
let retinaScale = UIScreen.main.scale
let retinaSquare = CGSize(width: size * retinaScale, height: size * retinaScale)//CGSizeMake(size * retinaScale, size * retinaScale)
let cropSizeLength = min(asset.pixelWidth, asset.pixelHeight)
let square = CGRect(x: 0, y: 0, width: cropSizeLength, height: cropSizeLength)//CGRectMake(0, 0, CGFloat(cropSizeLength), CGFloat(cropSizeLength))
let cropRect = square.applying(CGAffineTransform(scaleX: 1.0/CGFloat(asset.pixelWidth), y: 1.0/CGFloat(asset.pixelHeight)))

let manager = PHImageManager.default()
let options = PHImageRequestOptions()
var thumbnail = UIImage()

options.isSynchronous = true
options.deliveryMode = .highQualityFormat
options.resizeMode = .exact
options.normalizedCropRect = cropRect

manager.requestImage(for: asset, targetSize: retinaSquare, contentMode: .aspectFit, options: options, resultHandler: {(result, info)->Void in
thumbnail = result!
})
return thumbnail
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

//MARK:
//MARK: Collectioview methods
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return arr_img.count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",
for: indexPath)
let imgview : UIImageView = cell.viewWithTag(20) as! UIImageView
imgview.image = self.getAssetThumbnail(asset: self.arr_img.object(at: indexPath.row) as! PHAsset, size: 150)

return cell
}

}


Related Topics



Leave a reply



Submit