I have a UICollectionViewController (HomeViewController) with 3 cells.
Each cell is as big as the screen's size.
In the last cell I have another UICollectionView (collectionView) to display data.
This data should be refreshed every time I pull to refresh.
But that does not work.
This is the code so far:
HomeViewController
class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let thirdCellId = "thirdCell"
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let thirdCell = collectionView.dequeueReusableCell(withReuseIdentifier: thirdCellId, for: indexPath) as! ThirdCell
thirdCell.refreshControl.addTarget(self, action: #selector(refreshData), for: UIControlEvents.valueChanged)
return thirdCell
}
#objc func refreshData(sender: UIRefreshControl) {
let cell = sender.superview as! ThirdCell <--- gives error: Could not cast value of type 'UICollectionView' to 'ExploreCell'
cell.loadData()
cell.refreshControl.endRefreshing()
print("Did work")
}
}
ThirdCell code:
class ThirdCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
override init(frame: CGRect) {
super .init(frame: frame)
setupCollectionView()
loadData()
setupRefreshControl()
}
// --- CollectionView ---
lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.delegate = self
cv.dataSource = self
return cv
}()
func setupCollectionView() {
self.addSubview(collectionView)
// Setup constraints
}
// --- RefreshControl ---
var refreshControl: UIRefreshControl = {
let rfs = UIRefreshControl()
// Handle action in HomeViewController
return rfs
}()
func setupRefreshControl() {
if #available(iOS 10.0, *) {
collectionView.refreshControl = refreshControl
} else {
collectionView.addSubview(refreshControl)
}
refreshControl.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
refreshControl.bottomAnchor.constraint(equalTo: self.topAnchor, constant: 30).isActive = true
refreshControl.translatesAutoresizingMaskIntoConstraints = false
}
func loadData() {
// Load data
self.collectionView.reloadData()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Related
I have a viewController with a collectionView inside of it. I'm pretty sure that I have configured everything right yet it is not rendering any cells. I have added the appropriate delegates and data sources and double checked to see if the data is loading and it is but cells are not being populated
import UIKit
import UIKit
import Alamofire
import AlamofireNetworkActivityIndicator
import SwiftLocation
import CoreLocation
import AMScrollingNavbar
class NewHomeFeedControllerViewController: UIViewController {
let detailView = EventDetailViewController()
var allEvents = [Event]()
let customCellIdentifier1 = "customCellIdentifier1"
var grideLayout = GridLayout(numberOfColumns: 2)
let refreshControl = UIRefreshControl()
var newHomeFeed: NewHomeFeedControllerViewController?
let paginationHelper = PaginationHelper<Event>(serviceMethod: PostService.showEvent)
lazy var dropDownLauncer : DropDownLauncher = {
let launcer = DropDownLauncher()
launcer.newHomeFeed = self
return launcer
}()
// 1 IGListKit uses IGListCollectionView, which is a subclass of UICollectionView, which patches some functionality and prevents others.
let collectionView: UICollectionView = {
// 2 This starts with a zero-sized rect since the view isn’t created yet. It uses the UICollectionViewFlowLayout just as the ClassicFeedViewController did.
let view = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout())
// 3 The background color is set to white
view.backgroundColor = UIColor.white
return view
}()
func handleDropDownMenu(){
dropDownLauncer.showDropDown()
}
func configureCollectionView() {
// add pull to refresh
refreshControl.addTarget(self, action: #selector(reloadHomeFeed), for: .valueChanged)
collectionView.addSubview(refreshControl)
}
func reloadHomeFeed() {
self.paginationHelper.reloadData(completion: { [unowned self] (events) in
self.allEvents = events
if self.refreshControl.isRefreshing {
self.refreshControl.endRefreshing()
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
})
}
func categoryFetch(dropDown: DropDown){
navigationItem.title = dropDown.name
paginationHelper.category = dropDown.name
configureCollectionView()
reloadHomeFeed()
}
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
collectionView.contentInset = UIEdgeInsetsMake(15, 0, 0, 0)
navigationItem.title = "Home"
collectionView.dataSource = self
collectionView.delegate = self
collectionView.collectionViewLayout = grideLayout
collectionView.reloadData()
collectionView.register(CustomCell.self, forCellWithReuseIdentifier: customCellIdentifier1)
// self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(handleDropDownMenu))
self.navigationItem.leftBarButtonItem = backButton
configureCollectionView()
reloadHomeFeed()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? ScrollingNavigationController {
navigationController.followScrollView(self.collectionView, delay: 50.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.stopFollowingScrollView()
}
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
if let navigationController = navigationController as? ScrollingNavigationController {
navigationController.showNavbar(animated: true)
}
return true
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
grideLayout.invalidateLayout()
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allEvents.count
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: customCellIdentifier1, for: indexPath) as! CustomCell
let imageURL = URL(string: allEvents[indexPath.item].currentEventImage)
print(imageURL ?? "")
customCell.sampleImage.af_setImage(withURL: imageURL!)
return customCell
}
}
extension NewHomeFeedControllerViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item == 0 || indexPath.item == 1 {
return CGSize(width: view.frame.width, height: grideLayout.itemSize.height)
}else{
return grideLayout.itemSize
}
}
}
Any idea what could be going on?
Sorry you guys forgot to add this
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
Haha thanks for the help
I want a variable in my code that keeps track of the index of my UICollectionView, but I can't get it to work. After some troubleshooting, I've boiled down the code to the following, which if pasted into an empty viewController should work since no storyboard is involved. The animated gif illustrates the problem. Initially my variable "selectedItem" is equal to the UICollectionView Cell text which reflects the data = [0,1,2,3], but then when I swipe right, it immediately becomes off by 1. Then it stays off by 1 until at the last cell where it matches again. The pattern repeats when going in reverse. Thanks for any help --
import UIKit
class CodeCollView2: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var data = [0,1,2,3] //["0", "1", "2", "3" ]
let cellId = "cellId2"
var selectedItem = 0
lazy var cView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.isPagingEnabled = true
cv.dataSource = self
cv.delegate = self
return cv
}()
var indexLabel: UILabel = {
let label = UILabel()
label.text = ""
label.font = UIFont.systemFont(ofSize: 30)
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
cView.register(CCell2.self, forCellWithReuseIdentifier: cellId)
view.addSubview(cView)
cView.translatesAutoresizingMaskIntoConstraints = false
cView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
cView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
cView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
cView.heightAnchor.constraint(equalToConstant: 200).isActive = true
view.addSubview(indexLabel)
indexLabel.translatesAutoresizingMaskIntoConstraints = false
indexLabel.bottomAnchor.constraint(equalTo: cView.topAnchor).isActive = true
indexLabel.centerXAnchor.constraint(equalTo: cView.centerXAnchor).isActive = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return data.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CCell2
selectedItem = indexPath.item
indexLabel.text = "seletedItem = \(selectedItem)"
cell.itemValue = data[selectedItem]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.frame.size
}
}
//============== CVCell ==================
class CCell2: UICollectionViewCell {
var itemValue: Int? {
didSet {
if let val = itemValue {
itemLabel.text = "\(val)"
}
}
}
var itemLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 100)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .lightGray
addSubview(itemLabel)
itemLabel.translatesAutoresizingMaskIntoConstraints = false
itemLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
itemLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
As Nikita's answer mentions, cellForItemAt is called when a cell is going to be shown, even if you only see a bit of it and go back to the previous one, so you shouldn't use to decided what cell is at the centre.
scrollViewDidScroll is the right way of tracking which cell you have at the centre, and you can print what index you are on with something like this:
func scrollViewDidScroll(_ scrollView:UIScrollView)
{
let midX:CGFloat = scrollView.bounds.midX
let midY:CGFloat = scrollView.bounds.midY
let point:CGPoint = CGPoint(x:midX, y:midY)
guard
let indexPath:IndexPath = collectionView.indexPathForItem(at:point)
else
{
return
}
let currentPage:Int = indexPath.item
indexLabel.text = "seletedItem = \(currentPage)"
}
Tracking the selected item in the 'cellForItemAt' is not a good idea. I would suggest you to track it in the scrollViewDidScroll delegate method of the UIScrollViewDelegate.
Something like this should work:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let currentPage = cView.contentOffset.x / self.view.bounds.width
}
I'm trying to pass an image from a view controller to a UICollectionViewCell whenever I segue to the UICollectionViewController. Normally, I would just use the following code to pass the variable directly to the UICollectionViewController.
let myCollectionViewController = MyCollectionViewController(collectionViewLayout: UICollectionViewFlowLayout())
myCollectionViewController.selectedImage = myImageView?.image
navigationController?.pushViewController(myCollectionViewController, animated: true)
However, I have subclassed my UICollectionViewCell and have set up the cell as follows:
import UIKit
class myCollectionViewCell: UICollectionViewCell {
let imageView:UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .red
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
return iv
}()
var selectedImage: UIImage? {
didSet {
self.imageView.image = selectedImage
}
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
How do I directly pass my image directly to my UICollectionViewCell subclass during the segue?
Hope this helps you-:
import Foundation
class HomeController: UIViewController{
// STORED VARIABLE FOR CollectionView
lazy var CollectionView : UICollectionView = {
var layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 0
var collectionViews = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionViews.translatesAutoresizingMaskIntoConstraints = false
collectionViews.backgroundColor = UIColor.white
collectionViews.showsHorizontalScrollIndicator = false
collectionViews.showsVerticalScrollIndicator = false
collectionViews.dataSource = self
collectionViews.delegate = self
return collectionViews
}()
// APPLY CONSTRAINTS FOR CollectionView
func setUpCollectionView(){
view.addSubview(CollectionView)
CollectionView.register(HomeControllerCell.self, forCellWithReuseIdentifier: "cell")
CollectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
CollectionView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
CollectionView.topAnchor.constraint(equalTo: view.topAnchor,constant:92).isActive = true
CollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor,constant:-50).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
setUpCollectionView()
}
}
// EXTENSION FOR COLLECTION VIEW PARENT
extension HomeController:UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
// NUMBER OF SECTION IN TABLE
public func numberOfSections(in collectionView: UICollectionView) -> Int{
return 1
}
// NUMBER OF ROWS IN PARENT SECTION
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return 5
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
let Cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! HomeControllerCell
// PASS IMAGE (whatever you have) TO COMPUTED VARIABLE image
Cell.image = pass image here
return Cell
}
// SIZE FOR PARENT CELL COLLECTION VIEW
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
return CGSize(width: view.frame.width, height: 220)
}
}
CollectionViewCellClass-:
class HomeControllerCell: UICollectionViewCell {
//INITIALIZER
override init(frame: CGRect) {
super.init(frame: frame)
setUpview()
}
// STORED VARIABLE imageVIEW
let imageView:UIImageView = {
let iv = UIImageView()
iv.backgroundColor = .red
iv.contentMode = .scaleAspectFill
iv.translatesAutoresizingMaskIntoConstraints = false
iv.clipsToBounds = true
return iv
}()
// COMPUTED VARIABLE image
var image: UIImage? {
didSet {
self.imageView.image = image
}
}
// APPLY CONSTRAINTS FOR CELL VIEWS
func setUpview(){
// ADD imageView AS SUBVIEW
addSubview(imageView)
// APPLY CONSTRAINT ON IMAGE VIEW
imageView.leftAnchor.constraint(equalTo: self.leftAnchor,constant:5).isActive = true
//menuHeader.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: self.topAnchor,constant:12).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 50).isActive = true
imageView.widthAnchor.constraint(equalToConstant: 50).isActive = true
}
// REQUIRED INIT
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I have a UICollectionView in my UIViewController(wrapped in UINavigationContoller). In the UICollectionViewCell, I create a UIImageView with a gif url.(Using Kingfisher)
The imageView works as expected, but it's getting blank whenever I "try to" swipe back to previous UIViewController. And when I cancel the "swipe back gesture", the imageView shows the gif again.
Oddly enough, the imageView is not getting blank when I click the back indicator.
Also, if I set a static image to the imageView, the imageView does not get blank.
Does anyone know how to fix this issue?
Here is a demo:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.pushViewController(ViewController2(), animated: true)
}
}
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.whiteColor()
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 100, height: 100)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.clearColor()
collectionView.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "cell")
view.addSubview(collectionView)
collectionView.snp_makeConstraints { (make) in
make.top.equalTo(snp_topLayoutGuideBottom)
make.left.right.bottom.equalTo(view)
}
}
}
extension ViewController2: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell
cell.imageView.animationImages = [UIImage(named: "1")!, UIImage(named: "2")!]
cell.imageView.startAnimating()
return cell
}
}
class CollectionViewCell: UICollectionViewCell {
lazy var imageView: UIImageView = {
let view = UIImageView()
view.clipsToBounds = true
view.contentMode = .ScaleAspectFill
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
imageView.snp_makeConstraints { (make) in
make.edges.equalTo(contentView)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I think this is a UIImageView issue.
I have a tableViewCell with a collectionView, collectionView's cells are custom ones, they contains just a imageView.
Here is my test project
Here are DataSource required methods from my CollectionView class:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCell
let image = UIImage(named: listItems[indexPath.row])
cell.testImageView.image = image
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return listItems.count
}
When I try to set image for cell's imageView I get this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I have checked image, it isn't nil, but testImageView is, I get this error when I try to set image to collectionViewCell's testImageView.
How can I fix it?
EDIT1
Here is method called from tableViewController to fill collectionView's listItem
func load(listItem: [String]) {
self.listItems = listItem
reloadData()
}
Also if I remove code from collectionView cellForItemAt indexPath with this one all is working fine
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath)
let imageView = UIImageView(image:UIImage(named: listItems[indexPath.row]))
cell.backgroundView = imageView
You have mistaken your two view controllers. Your IB outlet is connected to a cell in a different view controller. I mean you can have multiple views in different controllers connected to a same IBOutlet, but in your case the one that loads first is not connected, so that is why it crashes.
This is the cell your outlet was connected to.
This is that you are trying to load (but did not connect IBOutlet to image view):
Just in case you want to use code instead..
import UIKit
class ImageCell : UICollectionViewCell {
private var imageView: UIImageView!
private var descLabel: UILabel!
public var image: UIImage? {
get {
return self.imageView.image
}
set {
self.imageView.image = newValue
}
}
public var imageDesc: String? {
get {
return self.descLabel.text
}
set {
self.descLabel.text = newValue
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.initControls()
self.setTheme()
self.doLayout()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initControls()
self.setTheme()
self.doLayout()
}
override func awakeFromNib() {
super.awakeFromNib()
}
func initControls() {
self.imageView = UIImageView()
self.descLabel = UILabel()
}
func setTheme() {
self.imageView.contentMode = .scaleAspectFit
self.descLabel.numberOfLines = 1
self.descLabel.lineBreakMode = .byWordWrapping
self.descLabel.textAlignment = .center
self.descLabel.textColor = UIColor.black
self.contentView.backgroundColor = UIColor.white
}
func doLayout() {
self.contentView.addSubview(self.imageView)
self.contentView.addSubview(self.descLabel)
self.imageView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 5).isActive = true
self.imageView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -5).isActive = true
self.imageView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 0).isActive = true
self.descLabel.leftAnchor.constraint(equalTo: self.contentView.leftAnchor, constant: 5).isActive = true
self.descLabel.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -5).isActive = true
self.descLabel.topAnchor.constraint(equalTo: self.imageView.bottomAnchor, constant: 5).isActive = true
self.descLabel.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -5).isActive = true
for view in self.contentView.subviews {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
}
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
private var collectionView: UICollectionView!
private var dataSource: Array<String>!
override func viewDidLoad() {
super.viewDidLoad()
self.initDataSource()
self.initControls()
self.setTheme()
self.registerClasses()
self.doLayout()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func initDataSource() {
self.dataSource = ["Image1", "Image2", "Image3", "Image4", "Image5", "Image6"]
}
func initControls() {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 117, height: 125)
layout.invalidateLayout()
self.collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
self.collectionView.delegate = self
self.collectionView.dataSource = self
}
func setTheme() {
self.collectionView.backgroundColor = UIColor.clear
self.edgesForExtendedLayout = UIRectEdge(rawValue: 0)
self.view.backgroundColor = UIColor.blue
}
func registerClasses() {
self.collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCellIdentifier")
}
func doLayout() {
self.view.addSubview(self.collectionView)
self.collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
self.collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
for view in self.view.subviews {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCellIdentifier", for: indexPath) as! ImageCell
let imageName = self.dataSource[indexPath.row]
cell.image = UIImage(named: imageName)
cell.imageDesc = imageName
return cell
}
}
http://imgur.com/o7O7Plw
maybe the "testImageView" outlet variable is not connected from the interface builder or there is no CollectionViewCell with reuseIdentifier "ImageCell". Check whether cell is nil or not using LLDB po command.