I`m trying to show a message only when my collection view is empty. Well, I try set return 1 when my if is true but when I have this, it only show one item in my collection view (even if I had more). And when I return this (code bellow) it shows all the items I have in my collection view but when I try to delete it, the last one is not "deletable", I mean, the last one stays there. How can I show this message only if I have no items in my collection view?
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if self.movies.count > 0 {
self.favCollectionView.backgroundView = nil
return self.movies.count
}
else {
let rect = CGRect(x: 0,
y: 0,
width: self.favCollectionView.bounds.size.width,
height: self.favCollectionView.bounds.size.height)
let noDataLabel: UILabel = UILabel(frame: rect)
noDataLabel.text = "No favorite movies yet."
noDataLabel.textAlignment = .center
noDataLabel.textColor = UIColor.gray
noDataLabel.sizeToFit()
self.favCollectionView.backgroundView = noDataLabel
return 0
}
}
I did it like this:
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 { return self.movies.count}
else if section == 1 {
if self.movies.count < 1 { return 1 }
else { return 0 }
}
return 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = favCollectionView.dequeueReusableCell(withReuseIdentifier: "FavCollectionCell", for: indexPath) as! FavoritesCollectionViewCell
if indexPath.section == 0 {
let movie = movies[indexPath.row]
let imgStg: String = movie.posterURL!
let imgURL: URL? = URL(string: imgStg)
let imgSrc = ImageResource(downloadURL: imgURL!, cacheKey: imgStg)
cell.favTitleLabel.text = movie.title
cell.favPosterImageView.layer.cornerRadius = cell.favPosterImageView.frame.size.width/2
cell.favPosterImageView.clipsToBounds = true
//image cache with KingFisher
cell.favPosterImageView.kf.setImage(with: imgSrc)
return cell
}
else {
let rect = CGRect(x: 0, y: 0, width: self.favCollectionView.frame.width, height: self.favCollectionView.frame.height)
let noDataLabel: UILabel = UILabel(frame: rect)
noDataLabel.text = "No favorite movies yet."
noDataLabel.textAlignment = .center
noDataLabel.textColor = UIColor.gray
noDataLabel.sizeToFit()
let cell = UICollectionViewCell()
cell.contentView.addSubview(noDataLabel)
return cell
}
}
For @Lamar's solution, but the app crashed with error:
I make use of the backgroundView
in an extension as such:
extension UICollectionView {
func setEmptyMessage(_ message: String) {
let messageLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height))
messageLabel.text = message
messageLabel.textColor = .black
messageLabel.numberOfLines = 0;
messageLabel.textAlignment = .center;
messageLabel.font = UIFont(name: "TrebuchetMS", size: 15)
messageLabel.sizeToFit()
self.backgroundView = messageLabel;
}
func restore() {
self.backgroundView = nil
}
}
and I use it as such:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (self.movies.count == 0) {
self.collectionView.setEmptyMessage("Nothing to show :(")
} else {
self.collectionView.restore()
}
return self.movies.count
}
Maybe little bit late but here is little more constraint based solution. Still may help some one.
First create some empty state message (You can also create own, more complex view with image or something).
lazy var emptyStateMessage: UILabel = {
let messageLabel = UILabel()
messageLabel.translatesAutoresizingMaskIntoConstraints = false
messageLabel.textColor = .darkGray
messageLabel.numberOfLines = 0;
messageLabel.textAlignment = .center;
messageLabel.font = UIFont.systemFont(ofSize: 15)
messageLabel.sizeToFit()
return messageLabel
}()
Then add two methods and call them whenever you like.
func showEmptyState() {
collectionView.addSubview(emptyStateMessage)
emptyStateMessage.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).activate()
emptyStateMessage.centerYAnchor.constraint(equalTo: collectionView.centerYAnchor).activate()
}
func hideEmptyState() {
emptyStateMessage.removeFromSuperview()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With