Outlet is nil in UICollectionViewCell - ios

I have a UICollectionViewCell defined like so:
import UIKit
class GalleryCellCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var image: UIImageView!
}
Xcode put this in automatically when I added the outlet. In my UICollectionViewController's
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
function, I then try to set an image. My code is
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! GalleryCellCollectionViewCell
let imagePackage = imagePackages?[indexPath.item]
let uiImage = imagePackage?.getUIImage()
cell.image.image = uiImage
return cell
}
In my variable viewer for the debugger, I can see that uiImage is not nil. However, cell.image is nil. Why would this be? Did I not link it up correctly in the storyboard?

You can access image with another approach using tag.
from Interface builder (IB) of the cell go to attribute tab (third tab) and set tag for the image (like 5)
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! GalleryCellCollectionViewCell
let imagePackage = imagePackages?[indexPath.item]
let uiImage = imagePackage?.getUIImage()
var cellImg:UIImageView = cell!.viewWithTag(5) as! UIImageView;
cellImg.image = uiImage
return cell
}

Related

Cannot set imageView in CollectionViewCell

In my code, I am trying to set the imageView of a UICollectionViewCell. The imageView is called cellImageView in the CollectionViewCell class. When the app loads up it tries to initialize this value, but it doesn't work
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "selectCell", for: indexPath) as! PhraseSelectionCell
cell.cellImageView?.image = UIImage(named: "lol")
return cell
}
Class of UICollectionViewCell
class PhraseSelectionCell: UICollectionViewCell {
#IBOutlet var cellImageView: UIImageView!
}
try debugging this way, then you can find where the bug is.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "selectCell", for: indexPath) as! PhraseSelectionCell
//debug 1
if UIImage(named: "lol") == nil {
print("image is nil, double check image name")
}
//debug 2
if cell.cellImageView == nil {
print("cellImageView outlet is nil")
}
cell.cellImageView?.image = UIImage(named: "lol")
return cell
}

My UICollectionViewCell item is nil?

My CollectionViewCell imageView is nil
My Cell File is here
class MyTicketsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imgTicket: UIImageView!
}
My Controller File Code is here
class MyTicketsCollectionViewController: UICollectionViewController {
var photos: [String] = ["ticket1","ticket2","ticket3","ticket4"]
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.register(MyTicketsCollectionViewCell.self, forCellWithReuseIdentifier: "MyTicketsCollectionViewCell")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return photos.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyTicketsCollectionViewCell", for: indexPath) as! MyTicketsCollectionViewCell
cell.imgTicket.image = UIImage(named: photos[indexPath.row])
return cell
}
}
Error is "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"
When I debug it then
cell.imgTicket is nil
How solve this issue?
Try changing your code to
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyTicketsCollectionViewCell", for: indexPath) as! MyTicketsCollectionViewCell
cell.imgTicket.image = UIImage(named: photos[indexPath.row])
return cell
}
You are dequeuing ActiveTicketsCollectionViewCell but the cell is registered under MyTicketsCollectionViewCell.
There is 2 possible solutions here...
1. Might be ActiveTicketsCollectionViewCell have not the property imgTicket or you mention a wrong cell class here as u have mentioned a different cell class name MyTicketsCollectionViewCell so try to write this code.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyTicketsCollectionViewCell", for: indexPath) as! MyTicketsCollectionViewCell
cell.imgTicket.image = UIImage(named: photos[indexPath.row])
return cell
2. Might be you have missed to connect your property (#IBOutlet weak var imgTicket: UIImageView!) with the Outlet (xib or storyboard).

Unhide the selected cells' 'tick' in a collectionView

I have a collectionView of images and I want to show when multiple of these cells are selected.
I use a simple cell.myUIImage.isHidden = false but nothing seems to work.
Multiple select is enabled in the Interface Builder and is set in viewDidLoad(), this is what I have:
#IBOutlet weak var myUIImage: UIImageView!
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItemView", for: indexPath) as! PhotoFeed
cell.myUIImage.isHidden = false
print ("cell was selected at:", indexPath.item)
photoCollection.reloadData()
}
You can not access UICollectionViewCell with dequeueReusableCell other than cellForItemAt indexPath method.
To access cell in didSelectItemAt indexPath use:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let collectionCell = collectionView.cellForItem(at: indexPath) as? PhotoFeed {
collectionCell.myUIImage.isHidden = false
print ("cell was selected at:", indexPath.item)
photoCollection.reloadData()
}
}
But again photoCollection.reloadData() will reload the cell and myUIImage will be hidden again.
So you need to maintain the selected indexes and show/hide in cellForItemAt indexPath. With the help of selectedIndexes you can have the functionality like show image on selection and hide image on select again.
You should have an array of selectedIndexes. Say
var selectedIndexes = [IndexPath]()
Add in didSelectItemAt indexPath, Update method as:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if selectedIndexes.contains(indexPath) {
if let index = selectedIndexes.index(of: indexPath) {
selectedIndexes.remove(at: index)
}
} else {
selectedIndexes.append(indexPath)
}
photoCollection.reloadData()
}
In cellForItemAt indexPath:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItemView", for: indexPath) as? PhotoFeed else {
fatalError("cell not found")
}
if selectedIndexes.contains(indexPath) {
cell.myUIImage.isHidden = false
} else {
cell.myUIImage.isHidden = true
}
return cell
}
You should create #IBOutlet for myUIImage in collectionviewcell:
class PhotoFeed: UICollectionViewCell {
#IBOutlet weak var myUIImage: UIImageView!
}
In ViewController:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoItemView", for: indexPath) as! PhotoFeed
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! PhotoFeed
cell.myUIImage.isHidden = !cell.myUIImage.isHidden
}

How to display image of selected UICollectioNViewCell in UIView? (Swift 3)

I am new to iOS development, so please bear with me if this is obvious.
I have a UICollectionView on the bottom half of a view controller; it currently displays all photos in my photo library. There is a UIView on the top half of the same view controller.
Q: When I select a UICollectionViewCell (i.e. a photo), how do I display that photo in the UIView on the same view controller?
I imagine I'll have to use didSelectItemAt somehow to save the index path of the selected image in order to display that image in the UIView. (I've included what I have thus far for didSelectItemAt.) How do I refresh the content of the UIView as different photos are selected?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedVideo = collectionView.cellForItem(at: indexPath)
selectedVideo?.alpha = 0.5
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let deselectedVideo = collectionView.cellForItem(at: indexPath)
deselectedVideo?.alpha = 1.0
}
put ImageView into your view then make IBOutlet of imageview . you get cell of collectionview , set image of collectionviewcell of imageview image into top imageView
You can try this
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedCell = collectionView.cellForItem(at: indexPath) as! MyCollectionViewCell
yourview.imageView.image = selectedCell.imageView.image
}
From my understanding on the comments you have described earlier, there are 2 ways you can implement.
Using UIViewController, drop a UIView and a UICollectionView.
Using UICollectionViewController, and create a UICollectionReusableView
I'm assuming that you are using the 1st method,
Drop an #IBOutlet for the above UIImageView and name it myImageView for example.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedImage = collectionView.cellForItem(at: indexPath)
myImageView.image = selectedImage.myImageView.image
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedVideo = collectionView.cellForItem(at: indexPath)
view.imageView.image = selectedVideo
}

Passing Data from a ViewController to a Collection Cell within a Table Cell

This may be a little confusing, but i have a view controller that has a table view that contains a custom table cell and within this table cell, I have a collectionView with each cell holding a single image. I am trying to configure my collectionCell's image using the userToView variable seen below.
The delegate function below is where the table cell is being configured:
OtherUserAccountViewController.swift
class OtherUserAccountViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var userToView = User()
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:OtherUserPhotosTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: photosCellReuseIdentifier) as! OtherUserPhotosTableViewCell
cell.selectionStyle = .none
return cell
}
...
}
The delegate function below is where this image is being set:
OtherUserPhotosTableViewCell.swift
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "otherUserPhotosCollectionCell", for: indexPath) as! OtherUserPhotosCollectionViewCell
//Configure cell with photo from parent ViewController
return cell
}
My custom CollectionViewCell can be seen below:
OtherUserPhotosCollectionViewCell.swift
class OtherUserPhotosCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
}
I have only really been getting accustomed to Swift & iOS development over the last couple weeks so any help is much appreciated. Thank you for your time!
Answered by assuming that you have UIImages already available to you
Assuming you have a single UICollectionViewCell
In OtherUserPhotosTableViewCell.swift
var photoFromTableView: UIImage?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "otherUserPhotosCollectionCell", for: indexPath) as! OtherUserPhotosCollectionViewCell
//Configure cell with photo from parent ViewController
if let photo:UIImage = photoFromTableView {
cell.imageView.image = photo
}
return cell
}
In OtherUserAccountViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:OtherUserPhotosTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: photosCellReuseIdentifier) as! OtherUserPhotosTableViewCell
cell.selectionStyle = .none
cell.photoFromTableView = //Image you want to pass
return cell
}
Assuming you have multiple UICollectionViewCells
In OtherUserPhotosTableViewCell.swift
var photosArray: [UIImage]?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "otherUserPhotosCollectionCell", for: indexPath) as! OtherUserPhotosCollectionViewCell
//Configure cell with photo from parent ViewController
if let photo_array:[UIImage] = photosArray {
cell.imageView.image = photo_array[IndexPath.row]
}
return cell
}
In OtherUserAccountViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:OtherUserPhotosTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: photosCellReuseIdentifier) as! OtherUserPhotosTableViewCell
cell.selectionStyle = .none
cell.photosArray = //Array of Images you want to pass
return cell
}

Resources