Reputation: 183
I am trying to add data from one view controller to a collection view controller which adds an element to the datasource array and then adds a cell to the collection view.
prepareforsegue
in previous ViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "unwindToCollectionView"{
let CVC = segue.destination as! CollectionViewController
if let image = image{
CVC.images.insert(imagePost(image:image), at: 0)
print("Image is not nil")
}
let index = IndexPath(item: 0, section: 0)
//CVC.collectionView?.reloadData()
CVC.collectionView?.collectionViewLayout.invalidateLayout()
CVC.collectionView?.layoutIfNeeded()
CVC.collectionView?.insertItems(at: [index])
//CVC.collectionView?.reloadItems(at: [index])
print("In prepare for segue: \(CVC.images.count)")
}
}
collectionViewController
cellForItemAt
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
// Configure the cell
cell.cellImageView.image = images[indexPath.row].image
cell.cellImageView.clipsToBounds = true
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
layout.itemSize = CGSize(width: (UIScreen.main.bounds.width-1)/2, height: (UIScreen.main.bounds.width-1)/2)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
collectionView.collectionViewLayout = layout
cell.cellImageView.layer.cornerRadius = CGFloat((cell.cellImageView.frame.width)/2)
return cell
}
Error received:
2018-01-25 11:43:16.228902-0500 CAR+CV(1.0)Server[4182:1181750] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot set the layout [] for [; layer = ; contentOffset: {0, -88}; contentSize: {375, 573}; adjustedContentInset: {88, 0, 83, 0}> collection view layout: ] during an update.
Upvotes: 0
Views: 782
Reputation: 77567
Very wrong way to do this...
First, set your collectionViewLayout
in viewDidLoad()
Next, in prepareForSegue
, you want to modify the collection view's Data, not the collection view itself.
So...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "unwindToCollectionView"{
let CVC = segue.destination as! CollectionViewController
if let image = image {
// add the image to the CollectionViewController's data
CVC.images.insert(imagePost(image:image), at: 0)
print("Image is not nil")
}
print("In prepare for segue: \(CVC.images.count)")
}
}
Then, your collection view's cellForItemAt
is simply:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
// Configure the cell
cell.cellImageView.image = images[indexPath.row].image
// don't do this here...
// cell.cellImageView.clipsToBounds = true
// cell.cellImageView.layer.cornerRadius = CGFloat((cell.cellImageView.frame.width)/2)
return cell
}
Edit: as a side note, setting .cornerRadius
should not be done in cellForItemAt
either, as the cell will not be laid-out yet. Much better to subclass UIImageView
and set the .cornerRadius
in layoutSubviews()
Edit 2:
class RoundImageView: UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
self.clipsToBounds = true
self.layer.cornerRadius = self.frame.width / 2.0
}
}
Just set the Class of your current UIImageView
to RoundImageView
.
"where do I call insertItems(at:[index])"
You don't need to do that. When your segue moves to the view controller, your collection view will reload and the image you just inserted into your images
array will become the first cell. I notice your segue identifier is "unwindToCollectionView"
- so if your collection view does not automatically reload, add this to the VC holding the collection view:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
collectionView.reloadData()
}
Upvotes: 1