How to Show a Collectionview Like Facebook Upload Image Using Swift 4

How to show a collectionView like facebook upload image using swift 4?

Your answer is in your question bro some short of conditions

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

switch indexPath.item {
case 0,1:
return CGSize(width: (UIScreen.main.bounds.width - 16) / 2, height: (UIScreen.main.bounds.width - 16) / 2)
default:
return CGSize(width: (UIScreen.main.bounds.width - 32) / 3, height: (UIScreen.main.bounds.width) / 3)
}
}

Swift - Facebook style image grid using UICollectionViewFlowLayout

Change this line:

let itemWidth:CGFloat = (width - 2 * padding) / 3.0

to this:

let itemWidth:CGFloat = floor((width - 2 * padding) / 3.0)

You may want to do that with a 2 item row as well.


Edit

The initial problem is that floating-point numbers are approximations.

So, on an iPhone 8, for example, the view width is 375 points. The cell width calculation of:

let padding: CGFloat = 5
let itemWidth:CGFloat = (width - 2 * padding) / 3.0

itemWidth ends up being 121.666... (repeating), which UIKit interprets as 121.66666666666667.

So, 121.66666666666667 * 3.0 + 10 equals (roughly) 375.00000000000011 and... that is greater than 375.0.

So, the collection view says "can't fit that on one row."

Using floor() fixes the problem, except... it hits a really weird bug!

If you change numberOfItemsInSection from 5 to 8, you'll get two rows of 3, and there will be no gap on the right.

We can get around this by making the side cells slightly narrower than the center cell like this:

// we want all three to be the same heights
// 1/3 of (width - 2 * padding)
let itemHeight: CGFloat = (width - 2 * padding) / 3.0

// left and right cells will be 1/3 of (width - 2 * padding)
// rounded down to a whole number
let sideW: CGFloat = floor(itemHeight)

// center cell needs to be
// full-width minus 2 * padding
// minus
// side-width * 2
let centerW: CGFloat = (width - 2 * padding) - sideW * 2

// is it left (0), center (1) or right (2)
let n = (item - 2) % 3

// use the proper width value
let itemWidth: CGFloat = n == 1 ? centerW : sideW

return CGSize(width: itemWidth, height: itemHeight)

Or, what seems to be working is making the width just slightly smaller than the floating-point 1/3rd. You used -0.1, but it also works with:

let itemWidth:CGFloat = ((width - 2 * padding) / 3.0) - 0.0000001

In any case, that hopefully explains the reason for the "2 cells instead of 3" issue, and two options for avoiding it.

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

}

Use ImagePicker to upload images into CollectionView

After appending the new image to your data source call YOUR_COLLECTION_VIEW.reloadData() just to display the new items which added recently to it's data source.

Show 3 images on 1st row and 3 images on second row on collectionview

Your code looks perfect but you may forgot to confirm the FlowLayout Protocol.
so,
you just need to confirm the below protocol in your code,

UICollectionViewDelegateFlowLayout

Hope this way may help you.



Related Topics



Leave a reply



Submit