Subviews are nil when UICollectionView and UICollectionViewCell are in XIB files - swift

Hi there! I've created a sample project that shows my problem exactly. Click to download!
I've created an app which contains a subclass of UICollectionViewCell, it contains an ImageView as subview. It also has a XIB file containing the view.
When I use this UICollectionViewCell within a UICollectionView that is directly embedded in a ViewController, the cell works just fine. Here's the code of the WorkingViewController containing the code that registers the cell:
class WorkingViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let cellNib = UINib(nibName: "ImageCell", bundle: nil)
collectionView.register(cellNib, forCellWithReuseIdentifier: "ImageCell")
collectionView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func randomInt(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max - min + 1))) + min
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as? ImageCell else {
fatalError("Could not load cell")
}
let randomNumber = randomInt(min: 1, max: 10)
cell.imageView.image = UIImage(named: "stockphoto\(randomNumber)")
return cell
}
}
Now move the Storyboard Entry Point over to the BuggyViewController. Here the UICollectionView is not directly embedded. It is contained within a UIView that also has an XIB. Here's the code for that view, containing the registering of the cell from earlier:
class DetailView: UIView, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet var contentView: UIView!
#IBOutlet weak var collectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
Bundle.main.loadNibNamed("DetailView", owner: self, options: nil)
self.addSubview(self.contentView)
self.contentView.frame = self.bounds
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.delegate = self
collectionView.dataSource = self
let cellNib = UINib(nibName: "ImageCell", bundle: nil)
collectionView.register(cellNib, forCellWithReuseIdentifier: "ImageCell")
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCell")
collectionView.reloadData()
}
func randomInt(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max - min + 1))) + min
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as? ImageCell else {
fatalError("Could not load cell")
}
let randomNumber = randomInt(min: 1, max: 10)
cell.imageView.image = UIImage(named: "stockphoto\(randomNumber)")
return cell
}
}
But this results in an error in the DetailView, line 55:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an
Optional value
So here the imageView of the cell is suddenly nil which makes me think I did something wrong registering the cell or instantiating it. But I just cannot resolve it.

You should delete the line where you register the cell class:
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCell")
Indeed you've defined your cell in a Nib and should register it through the method func register(_ nib: UINib?, forCellWithReuseIdentifier identifier: String). Registering it through the cellClass method will return nil.
And as the Apple doc states:
If you previously registered a class or nib file with the same reuse
identifier, the class you specify in the cellClass parameter replaces
the old entry. You may specify nil for cellClass if you want to
unregister the class from the specified reuse identifier.
This explains why you were getting nil.

Related

Swift - How to enable and generate horizontal scroll of UICollection View that is within a UITableViewCell?

I have a UICollectionView placed inside a UITableViewCell. The collection view has its scroll direction set to horizontal. However, when I swipe left or right on it to try and scroll, it doesn't work. Instead the table view cell is just pressed. It seems like the table view is eating up the gesture and not allowing the collection view to register it.
How can I make it so the collection view can scroll left and right with horizontal swipes, while still allowing the parent table view to scroll vertically?
Image that I want to the first cell to have a collection view of images horizontally and on the other cells rows of names for example .
you can see my project on this GitHub account : https://github.com/BenSeferidis/Nft-Assets/tree/version4 for better understanding .
the code is the following :
LobbyViewController (Main VC):
import UIKit
class LobbyViewController: UIViewController {
// MARK: - IBProperties
#IBOutlet weak var tableView: UITableView!
// MARK: - Properties
var data: [DataEnum] = []
var likes:[Int] = []
var numlikes: Int = 0
var nfts: [Nft] = []
let creators : [Creator] = []
var icons: [Icon] = []
var loadData = APICaller()
// MARK: - Life Cyrcle
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "AssetTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "AssetTableViewCell")
let nib2 = UINib(nibName: "CreatorsTableViewCell", bundle: nil)
tableView.register(nib2, forCellReuseIdentifier: "CreatorsTableViewCell")
tableView.dataSource = self //method to generate cells,header and footer before they are displaying
tableView.delegate = self //method to provide information about these cells, header and footer ....
downloadJSON {
self.tableView.reloadData()
print("success")
}
loadData.downloadData { (result) in
print(result)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? PresentViewController {
destination.nft = nfts[tableView.indexPathForSelectedRow!.row]
destination.delegate = self
}
}
// MARK: - Methods
func downloadJSON(completed: #escaping () -> ()) {
let url = URL(string: "https://public.arx.net/~chris2/nfts.json")
URLSession.shared.dataTask(with: url!) { [self] data, response, error in
if error == nil {
do {
self.nfts = try JSONDecoder().decode([Nft].self, from: data!)
nfts.forEach { nft in
let creators = nfts.map (\.creator)
self.data.append(.type1(creators: creators))
}
self.nfts.forEach { nft in
self.data.append(.type2(nft: nft))
}
DispatchQueue.main.async {
completed()
}
}
catch {
print("error fetching data from api")
}
}
}.resume()
}
}
// MARK: - Extensions
extension LobbyViewController : UITableViewDelegate , UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
indexPath.row == 0 ? 100 : UITableView.automaticDimension
}
//gemizo ta rows tou table
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch self.data[indexPath.item] {
case .type1(let creators):
let cell = tableView.dequeueReusableCell(withIdentifier: "CreatorsTableViewCell",
for: indexPath) as! CreatorsTableViewCell
//cell.creatorsCollectionView = self
return cell
case .type2(let nft):
let cell = tableView.dequeueReusableCell(withIdentifier: "AssetTableViewCell",
for: indexPath) as! AssetTableViewCell
cell.nameLabel?.text = nft.name
cell.nameLabel.layer.cornerRadius = cell.nameLabel.frame.height/2
cell.likesLabel?.text = "\((numlikes))"
let imgUrl = (nft.image_url)
print(imgUrl)
cell.iconView.downloaded(from: imgUrl)
cell.iconView.layer.cornerRadius = cell.iconView.frame.height/2
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetails", sender: self)
}
}
extension LobbyViewController : TestDelegate{
func sendBackTheLikess(int: Int) {
numlikes = int
tableView.reloadData()
}
}
// MARK: - Enums
enum DataEnum {
case type1(creators: [Creator])
case type2(nft: Nft)
}
// MARK: - Struct
struct Constants {
static let url = "https://public.arx.net/~chris2/nfts.json"
}
Creators TableViewCell :
import UIKit
class CreatorsTableViewCell: UITableViewCell {
//MARK: - IBProtperties
#IBOutlet var creatorsCollectionView: UICollectionView!
#IBOutlet var creatorsLbl: UILabel!
//MARK: - Properties
var nft : Nft?
var creators : [Creator] = []
var users: User?
weak var delegate : CreatorsTableViewCellDelegate?
//MARK: - Life Cyrcle
override func awakeFromNib() {
super.awakeFromNib()
creatorsCollectionView.dataSource = self
creatorsCollectionView.delegate = self
let nibName = UINib(nibName: "CollectionViewCell", bundle: nil)
creatorsCollectionView.register(nibName, forCellWithReuseIdentifier: "CollectionViewCell")
creatorsCollectionView.horizontalScrollIndicatorInsets
}
//init
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 10 , height: 10)
layout.sectionInset = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)
super.init(style: style, reuseIdentifier: reuseIdentifier)
creatorsCollectionView.showsHorizontalScrollIndicator = true
creatorsCollectionView.showsVerticalScrollIndicator = false
}
required init?(coder aDecoder : NSCoder) {
super.init(coder: aDecoder)
}
func setUpCollection(creators: Creator) {
creatorsLbl.text = creators.user.username
}
}
//MARK: - Extensions
extension CreatorsTableViewCell : UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return creators.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = creatorsCollectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell",
for: indexPath) as! CollectionViewCell
// cell.setUpCollectionViewCell((nft?.creator.profileImgURL[indexPath.row])!)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.deselectItem(at: indexPath, animated:true)
}
}
//MARK: - Protocols
protocol CreatorsTableViewCellDelegate: AnyObject {
func didSelectPhoto(index: Int)
}
CollectionViewController :
import UIKit
private let reuseIdentifier = "Cell"
class CollectionViewController: UICollectionViewController , UICollectionViewDelegateFlowLayout {
let creatorsCellId = "creatorsCellId"
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
// self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
func setupCollectionView() {
collectionView?.showsHorizontalScrollIndicator = false
collectionView?.backgroundColor = .lightGray
let nib = UINib(nibName: "CollectionViewCell", bundle: nil)
collectionView?.register(nib, forCellWithReuseIdentifier: creatorsCellId)
collectionView?.register(CollectionViewCell.self, forCellWithReuseIdentifier: "cellId")
}
}
}
extension CollectionViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: creatorsCellId, for: indexPath) as! CollectionViewCell
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 180, height: view.frame.height-60)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
}
}
CollcetionViewCell:
import UIKit
class CollectionViewCell: UICollectionViewCell {
//MARK: - IBProperties
#IBOutlet var creatorsImg: UIImageView!{
didSet {
creatorsImg.contentMode = .scaleAspectFit
}
}
//MARK: - Properties
var nft : Nft?
//MARK: - Life Cyrcle
override func awakeFromNib() {
super.awakeFromNib()
}
func setUpCollectionViewCell(_ nft: Nft) {
let imgUrl = (nft.creator.profileImgURL)
print(imgUrl)
creatorsImg.downloaded(from: imgUrl)
// creatorsImg.image = UIImage(named: (nft.creator.profileImgURL))
creatorsImg.layoutIfNeeded()
creatorsImg.layer.cornerRadius = creatorsImg.frame.height / 2
}
}
the results is this :

Xcode Swift error by casting my own collectionViewCell

I tried to create my own collectionViewCell. But by casting it in the cellForItemAt indexPath method it throws an error.
I donĀ“t know why.
i hope you can help me.
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
// MARK: Outlets
#IBOutlet weak var testCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.testCollectionView.register(TestCollectionViewCell.self, forCellWithReuseIdentifier: "testCell")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "testCell", for: indexPath) as! TestCollectionViewCell
cell.testLabel.text = "Hihi Test!"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 80)
}
}
This is the collectionViewCell class:
import UIKit
class TestCollectionViewCell: UICollectionViewCell {
var testLabel: UILabel = {
let label = UILabel()
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(testLabel)
testLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
testLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And this is the error by starting the app:
First, register your cell into viewDidLoad method like that:
testCollectionView.register(UINib(nibName: "TestCollectionViewCell", bundle: Bundle(for: type(of: self))), forCellWithReuseIdentifier: "testCell")

How can I update a UICollectionView from another class?

I am trying this for a couple of days now and haven't achieved anything yet. What I am trying to do is when a user picks a User item form the ViewController class, I want to save it in Realm and show it in the CollectionView of the SavedInterestsViewController class. I use a delegate pattern as suggested in this post How to access and refresh a UITableView from another class in Swift, but unfortunately I still receive nil, I guess because the GC removed the collectionView outlet already right? (please correct me if I misunderstood it). However, how can I get this to work by using a delegate pattern? Here is my code, this is the class where the user Picks a new User-item:
protocol ViewControllerDelegate {
func didUpdate(sender: ViewController)
}
class ViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var collectionView: UICollectionView!
var delegate: ViewControllerDelegate?
let numberOfTweets = 5
let realm = try! Realm()
var image = UIImage()
var imageArray: [String] = []
var userArray: [User] = []
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell")
searchBar.delegate = self
}
}
extension ViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
print("One second...")
let functionClass = NetworkingFunctions()
var loopCount = 0
functionClass.getWikipediaAssumptions(for: searchBar.text!) { [self] (articleArray) in
self.userArray.removeAll()
for x in articleArray {
functionClass.performWikipediaSearch(with: x, language: WikipediaLanguage("en")) { (user) in
self.userArray.append(user)
collectionView.reloadData()
loopCount += 1
}
}
}
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userArray.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionViewCell
let image = UIImage.init(data: userArray[indexPath.item].image as Data)
cell.userImage.image = image
cell.nameLabel.text = userArray[indexPath.item].name
cell.userImage.layer.borderColor = image?.averageColor?.cgColor
if userArray[indexPath.item].checked == false {
cell.checkmark.isHidden = true
} else {
cell.checkmark.isHidden = false
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if userArray[indexPath.item].checked == false {
userArray[indexPath.item].checked = true
collectionView.reloadData()
let newUser = User()
newUser.image = userArray[indexPath.item].image
newUser.name = userArray[indexPath.item].name
newUser.checked = true
try! realm.write {
realm.add(newUser)
}
self.delegate = SavedInterestsViewController()
self.delegate?.didUpdate(sender: self)
}
else {
userArray[indexPath.item].checked = false
collectionView.reloadData()
}
}
}
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = UIScreen.main.bounds.width/3 - 10
let height = width
return CGSize(width: width, height: height)
}
}
class User: Object {
#objc dynamic var image: NSData = NSData()
#objc dynamic var name: String = ""
#objc dynamic var checked: Bool = false
}
... and this is the class where I want to show the selected item, after the User clicked on the 'Back' Button of the navigation controller of the ViewController class:
class SavedInterestsViewController: UIViewController, ViewControllerDelegate {
func didUpdate(sender: ViewController) {
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
#IBOutlet weak var addButton: UIBarButtonItem!
#IBOutlet weak var collectionView: UICollectionView!
let realm = try! Realm()
var userArray: [User] = []
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionCell")
fetchDataFromRealm()
}
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "SavedToNew", sender: self)
}
func fetchDataFromRealm() {
userArray.append(contentsOf: realm.objects(User.self))
collectionView.reloadData()
}
}
extension SavedInterestsViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionViewCell
let image = UIImage.init(data: userArray[indexPath.item].image as Data)
cell.userImage.image = image
cell.nameLabel.text = userArray[indexPath.item].name
cell.userImage.layer.borderColor = image?.averageColor?.cgColor
if userArray[indexPath.item].checked == false {
cell.checkmark.isHidden = true
} else {
cell.checkmark.isHidden = false
}
return cell
}
}
extension SavedInterestsViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = UIScreen.main.bounds.width/3 - 10
let height = width
return CGSize(width: width, height: height)
}
}
in your code you have lines
self.delegate = SavedInterestsViewController()
self.delegate?.didUpdate(sender: self)
but it do mostly nothing - you set the delegate to newly created class, didUpdate it - but I don't see any use of it - you don't present it in any way.
If I understand you right - you have SavedInterestsViewController, from it - you open ViewController, do something and when back to SavedInterestsViewController. (I can be wrong with your flow - correct me if so)
In this flow - you have delegate property in ViewController, but it must be of type SavedInterestsViewController. And you have to set it to SavedInterestsViewController when you open ViewController from it. And later in ViewController you have to call didUpdate method of delegate.

How can I get an array of Strings i.e.. [String] to show up in the custom collection view cell using storyboard

In the Storyboard:
The datasource and delegate are connected from the LFCollectionView to the LFCollectionViewController. The reuseIdentifier is set to LFCell in the CollectionViewCell. The label inside the CollectionViewCell is named cellLabel and has an outlet to my custom LFCollectionViewCell. I want the outlet cellLabel to display the elements in my array of strings lFContainerLabel within each cell container in the collection. I am missing something, or going about this all wrong. I do not have a nib. I don't know how to use those. Is a nib a must in this scenario?
import UIKit
var lFContainerLabel: [String] = []
private let reuseIdentifier = "LFCell"
class LFCollectionView: UICollectionView { }
class LFNavigationController: UINavigationController { }
class LFCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var cellLabel: UILabel!
}
class LFCollectionViewController: UICollectionViewController,UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.register(LFCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in LFCollectionViewController: UICollectionView) -> Int {
return 1
}
override func collectionView(_ LFCollectionViewController: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return lFContainerLabel.count
}
override func collectionView(_ LFCollectionViewController: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let lFCell = LFCollectionViewController.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as UICollectionViewCell!
var myIndex: Int = 0
lFCell?.backgroundColor = UIColor.black
lFCell?.accessibilityElements = lFContainerLabel
myIndex = indexPath.item
lFCell?.cellLabel?.text = lFContainerLabel[myIndex]
return lFCell!
}
}

App crashes with fatal error for setting image to CustomViewCell

I have created an UICollectionView with custom UICollectioViewCell with just an image view. When I try add an image to the image view in the cell it crashes with
fatal error: unexpectedly found nil while unwrapping an Optional value.
I'm unable to figure out where i'm getting the nil value from.
Below is my code for the CollectionViewController.
class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let reuseIdentifier = "Cell"
#IBOutlet weak var menuButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.registerClass(PhotoViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: UICollectionViewDataSource
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! PhotoViewCell
// Configure the cell
cell.backgroundColor = UIColor.grayColor()
cell.cellImageView.image = UIImage(named:"IMG_1635")// The code crashes here....
return cell
}
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}
}
// Code for Custom Cell
class PhotoViewCell: UICollectionViewCell {
#IBOutlet weak var cellImageView: UIImageView!
}
The app runs fine when on removing the following line cell.cellImageView.image = UIImage(named:"IMG_1635")
Try:
cell.cellImageView.image = UIImage(named:"IMG_1635")