Why is sizeForItemAtIndexPath never called? - swift2

In my custom view controller defined as follows:
class Wall : UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, WallLayoutDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let layout = WallLayout()
layout.delegate = self
let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
collectionView.registerClass(WallCell.self, forCellWithReuseIdentifier: Wall.reuseIdentifier)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.backgroundColor = UIColor.blackColor()
self.view.addSubview(collectionView)
self.collectionView = collectionView
}
// CODE
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(50, 100)
}
}
The function sizeForItemAtIndexPath is never called. How it comes?

I found that it is because the layout is up to me when I use UICollectionViewDelegateFlowLayout and cannot be deduced by the collection view.

Related

Increasing `collectionViewContentSize` width causes CollectionView Cells to disappear

So I have an issue I've been battling with for days now. I have a collectionView which is designed to have large cells (width-wise) which go off screen. The height is fixed. The idea is to basically scroll to the end (see below):
To achieve being able to scroll left and right, I've had to override the width inside collectionViewContentSize in my flowLayout. Like below.
override var collectionViewContentSize: CGSize {
var size = super.collectionViewContentSize
size.width = largeWidth
return size
}
This achieves increasing the horizontal scroll area (which is what I want) but the cells start to disappear once I reach a certain point. It's almost as if the cells are being dequeued when they shouldn't be. Any ideas on this. This is the final straw for my project but I'm out of ideas.
Many thanks
Code snippet can be found below. You should be able to just copy and paste this into any project:
class HomeViewController: UIViewController {
let collectionView: UICollectionView
let collectionViewLayout = CustomCollectionViewFlowLayout()
init() {
collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
super.init(nibName: nil, bundle: nil)
collectionView.backgroundColor = UIColor.red.withAlphaComponent(0.4)
collectionView.register(SomeCell.self, forCellWithReuseIdentifier: "SomeCell")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
collectionView.delegate = self
collectionView.dataSource = self
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.frame = view.bounds
view.addSubview(collectionView)
}
}
class SomeCell: UICollectionViewCell {
}
extension HomeViewController: UICollectionViewDataSource,
UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 150
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SomeCell", for: indexPath) as! SomeCell
cell.backgroundColor = .blue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 10000, height: 70)
}
}
class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {
override var collectionViewContentSize: CGSize {
var size = super.collectionViewContentSize
size.width = 10000
return size
}
}

How to do horizontally autoscroll for colletionViewCell?

I have a collectionView at the top of my App view and I want to display some ads inside it,
I made a ready array for some pictures that I want to display them in the collection view.
Now I'm looking for a method that I can make them horizontally scroll automatically.
class HomeVC: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionViewCell()
}
#IBOutlet weak var collectionView: UICollectionView!
var array = [ "https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcR8aTilga7j-8GfP4OUXUx1bV3E2EJaFt29QdSBD8OgcLBLCUiG&usqp=CAU?",
"https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRVq4AqZIDQ_UPnSd-PxQGkEutZnlu76NbZ4xETWelVnULLJ614&usqp=CAU",
"https://scontent.ffjr1-2.fna.fbcdn.net/v/t1.0-9/72577_563558293672959_39183751_n.jpg?_nc_cat=101&_nc_sid=dd9801&_nc_ohc=YySniLzpf_sAX-B8YFE&_nc_ht=scontent.ffjr1-2.fna&oh=12da3f0ae2404066684d742b4f785cfc&oe=5ED9FCDA",
"https://img.particlenews.com/image.php?type=thumbnail_1024x576&url=2zUI4r_0OJWDY4z00",
"https://content3.jdmagicbox.com/comp/def_content/advertising_agencies/default-advertising-agencies-9.jpg",
"https://miro.medium.com/max/895/1*2gq5_jgNSYJnLzCqIIYVGA.jpeg"]
}
Here below my registered cell that I want to make the autoscroll inside it by infinite array looping .
So can you help me how to do that?
extension HomeVC: UICollectionViewDelegate, UICollectionViewDataSource {
func setupCollectionViewCell () {
collectionView.delegate = self ; collectionView.dataSource = self
collectionView.register(UINib(nibName: "homeAdCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "adCell")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return array.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewlayout: UICollectionViewLayout, sizeForItemAt IndexPath: IndexPath) -> CGSize {
print ("Size func called")
return CGSize(width: 250, height: 75)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "adCell", for: indexPath) as! homeAdCollectionViewCell
cell.update(SURL: array[indexPath.row])
return cell
}
}
Set the Timer in ViewDidLoad and scroll to next item using collectionView.ScrollToitem method
If you want infinite scrolling with autoscroll effect, you can check this library:
https://github.com/WenchaoD/FSPagerView

How to pass images from collection view to collection view

I am struggled in passing images from collection view cell to another collection view cell.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main" , bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "ImageViewController") as! ImageViewController
let imageItem = image[indexPath.row]
vc.images = imageItem.image
self.navigationController?.pushViewController(vc, animated: true)
}
then in ImageViewController
class ImageViewController: UIViewController ,UICollectionViewDelegate , UICollectionViewDataSource {
#IBOutlet weak var imageCollectionView: UICollectionView!
var image: string!
override func viewDidLoad() {
super.viewDidLoad()
self.imageCollectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return image.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! imageCollectionViewCell
let url: URL = NSURL(string: image)! as URL
cell.images.af_setImage(withURL: url)
return cell
}
import UIKit
//for the firstVC
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let mainStoryboard:UIStoryboard = UIStoryboard(name: "Main" , bundle: nil)
if let vc = mainStoryboard.instantiateViewController(withIdentifier: "ImageViewController") as? ImageViewController
vc.reciveImageFromFirstVC = image[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
// for the second page image view controller
class ImageViewController : UIViewController {
var image:String!
var reciveImageFromFirstVC : String? {
didSet {
guard let reciveImg = reciveImageFromFirstVC else {
print("Can't get image for some reason")
return}
self.image = reciveImg
self.imageCollectionView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = imageCollectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! imageCollectionViewCell
let url: URL = NSURL(string: image)! as URL
cell.images.af_setImage(withURL: url)
return cell
}
}
i hope i helped you
thanks

Static cells from xib in UICollectionViews with segues (Swift 2)

I would like to create list of rows using UICollectionView with each row can click and go to another controller.
I create custom cell in xib and class for it.
This is my code:
class CollectionCellXIB: UICollectionViewCell {
#IBOutlet weak var label: UILabel!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
class Collection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell: CollectionCellXIB
self.collectionView!.registerNib(UINib(nibName: "CollectionCellXIB", bundle: nil), forCellWithReuseIdentifier: "cell")
if indexPath.row == 0 {
cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionCellXIB
cell.label.text = "cell 1"
} else {
cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionCellXIB
cell.label.text = "cell 2"
}
return cell
}
}
Unfortunatelly, segues not working. When I clicked on a row, nothing happend. Method shouldPerformSegueWithIdentifier wasn't called.
So, question is, how to use custom cells with xib and using segues?

Trouble passing data from TableViewCell labels to a ViewController

I am trying to pass data from the selected cell of an "Events" table view, to a "Details" View Controller. I have looked at various questions similar to mine, but I can't seem to properly apply it to my code. I also used labels, instead of a Subtitle style. There is also an image that needs to be passed.
my view controller looks like this:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
var names = ["BTown Diner", "Dunnkirk", "Chocolate Mousse", "Lil Wayne", "Annie", "Campus Squad Social"]
var details = ["Free drink with meal after 12 AM", "LADIES drink free", "10% off all ice cream!", "Lil 500 concert", "an IU Theater Production", "Bring your Squad to the Campus Squad Social"]
var images = [UIImage(named: "btown"), UIImage(named: "dunn"), UIImage(named: "choco"), UIImage(named: "lilwayne"), UIImage(named: "default"), UIImage(named: "default")]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
cell.name.text = names[indexPath.row]
cell.detail.text = details[indexPath.row]
cell.photo.image = images[indexPath.row]
return cell
}
var valueToPass:String!
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
// Get Cell Label
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
valueToPass = currentCell.textLabel.text
performSegueWithIdentifier("detailsSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "detailsSegue") {
// initialize new view controller and cast it as your view controller
var viewController = segue.destinationViewController as detailsViewController
// your new view controller should have property that will store passed value
viewController.passedValue = valueToPass
}
}
}
and here is my customCell.swift file:
import UIKit
class CustomCell: UITableViewCell {
#IBOutlet var photo: UIImageView!
#IBOutlet var name: UILabel!
#IBOutlet var detail: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I am very new to Swift, and it has proven to be very challenging for me. I'm really not a coder, however a project demands that I complete some of the coding for an application that I am the UI/UIX designer of. Thank you for your help in advance!
Try to register your "CustomCell" with the name "cell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "cell")
}
Here is a slight variation on your code starting with the main view controller...
import UIKit
class EventTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {
var names = ["BTown Diner", "Dunnkirk", "Chocolate Mousse", "Lil Wayne", "Annie", "Campus Squad Social"]
var details = ["Free drink with meal after 12 AM", "LADIES drink free", "10% off all ice cream!", "Lil 500 concert", "an IU Theater Production", "Bring your Squad to the Campus Squad Social"]
var images = [UIImage(named: "btown"), UIImage(named: "dunn"), UIImage(named: "choco"), UIImage(named: "lilwayne"), UIImage(named: "default"), UIImage(named: "default")]
override func viewDidLoad() {
super.viewDidLoad()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
cell.name.text = names[indexPath.row]
cell.detail.text = details[indexPath.row]
cell.photo.image = images[indexPath.row]
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "detailsSegue" {
guard let eventVC = segue.destinationViewController as? DetailsViewController,
let eventIndex = tableView.indexPathForSelectedRow?.row else {
return
}
eventVC.eventName = names[eventIndex]
eventVC.eventDetail = details[eventIndex]
eventVC.eventPhoto = images[eventIndex]
}
}
}
and then a sample detailsViewController...
import UIKit
class DetailsViewController: UIViewController {
var eventName: String = ""
var eventDetail: String = ""
var eventPhoto: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
print(eventName)
print(eventDetail)
}
}
You were off to a good start. Hope this helps get you the rest of the way.

Resources