I'm developing an application for tvOS. It has a tableview and each row of the tableview contains a collectionview. Tableview's focus is disabled so that collectioview cells get focused. When I return a static number as the collectionview items count, the cells are rendered. But when the items count is set dynamically, the cells are not rendered.
The code I used is given below:
class CategoryCVContainerCell: UITableViewCell {
#IBOutlet weak var categoryCollectionView: UICollectionView!
var cellType:CellType?
var sourceViewController: UIViewController?
var media : Media?
override func awakeFromNib() {
super.awakeFromNib()
categoryCollectionView.register(UINib(nibName: "VODType1CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "VODType1CollectionViewCell")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configureCellUI() {
categoryCollectionView.reloadSections(IndexSet(integer: 0))
}
}
extension CategoryCVContainerCell : UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("////////************------------////////// \(categoryDetails?.media?.count ?? 0)")
let itemsCount = categoryDetails?.media?.count ?? 0 //this code won't render cells
// let itemsCount = 10 // this code works
return itemsCount
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "VODType1CollectionViewCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 400.0, height: 250.0)
}
}
Related
As of title, I'm having trouble with the issue of nesting collectionViews. I found a workaround gimmicky solution but I'm not really satisfied with the result:
class ViewController3: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var outCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
outCollection.dataSource = self
outCollection.delegate = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath:
IndexPath) -> UICollectionViewCell {
let cell = outCollection.dequeueReusableCell(withReuseIdentifier: "outCell", for:
indexPath) as! CollectionViewCell
cell.backgroundColor = .green
cell.setViewDD() // gimmick HERE
return cell
}
}
and for the CollectionViewCell
class CollectionViewCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var inCollection: UICollectionView!
func setViewDD() {
self.inCollection.delegate = self
self.inCollection.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = inCollection.dequeueReusableCell(withReuseIdentifier: "inCell", for: indexPath) as! innercellulosa
cell.backgroundColor = .red
return cell
}
}
if I try to set the delegate and datasource of the innerCollection (either in VC3 or CVCell) I stumble in multiple problems which I can't solve.
I need to display images in collection view cells but when I'm trying to do that I'm getting 10 empty cells and I don't know where im making mistakes
Here is my code of ViewController
class NewGalleryViewController: UIViewController {
var presenter: ViewToPresenterPhotoProtocol?
var builder: GalleryRequestBuilder?
#IBOutlet var collectionView: UICollectionView!
let reuseIdentifier = "customCVCell"
#objc func refresh() {
presenter?.refresh()
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupPresenterIfNeed()
presenter?.viewDidLoad()
// Do any additional setup after loading the view.
}
func setupPresenterIfNeed() {
self.collectionView.backgroundColor = UIColor.white
if self.presenter == nil {
let presenter = GalleryPresenter()
presenter.view = self
self.presenter = presenter
self.builder = GalleryRequestBuilder()
}
}
}
extension NewGalleryViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.presenter?.photos.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PhotoCollectionViewCell
KFImage.url(builder?.createImageUrl(name: (presenter?.photos[indexPath.item].name)!))
.onSuccess { result in
cell.imageView.image = result.image
}
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 180, height: 128)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}
func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 20.0
}
// MARK: - UICollectionViewDelegate protocol
private func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
// handle tap events
print("You selected cell #\(indexPath.item)!")
}
}
extension NewGalleryViewController: PresenterToViewPhotoProtocol{
func onFetchPhotoSuccess() {
self.collectionView.reloadData()
self.collectionView!.collectionViewLayout.invalidateLayout()
self.collectionView!.layoutSubviews()
self.collectionView.refreshControl?.endRefreshing()
}
func onFetchPhotoFailure(error: String) {
print("View receives the response from Presenter with error: \(error)")
self.collectionView.refreshControl?.endRefreshing()
}
}
And Here is the code of cell
class PhotoCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
I've checked the link I'm making request to and it works. So problem is not in link. Maybe I should reload items after getting images?
You should set your UICollectionView delegate and data source once the view is loaded:
override func viewDidLoad() {
super.viewDidLoad()
// Add this lines
collectionView.delegate = self
collectionView.dataSource = self
self.setupPresenterIfNeed()
presenter?.viewDidLoad()
}
I have the following code:
class FinalImageViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var not: [UIImage?] = [#imageLiteral(resourceName: "silly5"), #imageLiteral(resourceName: "special16")]
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 3
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return not.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CVImageView", for: indexPath) as! CVCell
cell.cellImageView.image = not[indexPath.row]
return cell
}
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
print(ImagesOnClick)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(CVCell.self, forCellWithReuseIdentifier: "CVImageView")
}
}
And my cell:
class CVCell: UICollectionViewCell {
#IBOutlet weak var cellImageView: UIImageView!
}
Then in my storyboard I have set the imageView tag to 3, the cell identifier to CVImageView, but when I run the project the collection view is just all white and no items are showing. By the way if you're wondering what the ImagesOnClick is, it is just an array of the users selected images.
You can find your class name in storyboard, it should look like this
class FinalImageViewController: UIViewController,UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return ImagesOnClick.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withIdentifier: "CVImageView", for: indexPath) as! CVImageCell //replace CVImageCell with your cell class name
cell.imageView.image = ImagesOnClick[indexPath.row] //replace imageView with your image view name with tag=3
return cell
}
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
print(ImagesOnClick)
collectionView.register(CVImageCell.self, forCellWithReuseIdentifier: "CVImageView") //replace CVImageCell with your cell class name
collectionView.delegate = self
collectionView.dataSource = self
}
}
I would like to have UICollectionView with Horizontal Scrolling and Layout each section on it's own row from left to right.
Currently my CollectionView with Horizontal Scrolling has a vertical layout for each section.
Ideally I would like the following layout with horizontal scrolling:
So my question is how can I have horizontal scrolling on my UICollectionView where each horizontal row from left to right is laid out in one row. (see second diagram) Each section would occupy a different row.
Also each row should scroll horizontally at the same time (like a spreadsheet).
You have to combine Collection-view and Tableview for having horizontal scrolling on UICollectionView where each horizontal row from left to right is laid out in one row. Each section would occupy a different row.
class DesignCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var lbltext: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
class DesignTableViewCell: UITableViewCell {
#IBOutlet weak var designCollectionView: UICollectionView!
var numberofScection = Int()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.designCollectionView.register(UINib(nibName: "DesignCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "DesignCollectionViewCell")
self.designCollectionView.dataSource = self
self.designCollectionView.delegate = self
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
self.designCollectionView.collectionViewLayout = layout
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension DesignTableViewCell: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DesignCollectionViewCell", for: indexPath) as! DesignCollectionViewCell
cell.lbltext.text = "section \(self.numberofScection) indexpath \(indexPath.row)"
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 170, height: 100.0)
}
}
class ViewController: UIViewController {
#IBOutlet weak var designTableViewCell: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.designTableViewCell.register(UINib(nibName: "DesignTableViewCell", bundle: nil), forCellReuseIdentifier: "DesignTableViewCell")
self.designTableViewCell.dataSource = self
self.designTableViewCell.delegate = self
}
}
extension ViewController: UITableViewDataSource,UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DesignTableViewCell") as! DesignTableViewCell
cell.designCollectionView.reloadData()
cell.numberofScection = indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 110
}
}
I am trying to programmatically create a Collection View with six cells. The iPhone Simulator in Xcode 8 told me that my build was successful. There is still an error though.
Any help spotting the bug or bugs that are causing my cells not to display in the Simulator is greatly appreciated. (I put the Collection View directly into the IB from the Object Library. Also, I want each cell to occupy the entire size of the Collection View, hence displayedCellDimensions, because the user will segue between cells when a forward or backward button is tapped.) Thank you!
import UIKit
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
//MARK: - Collection View Properties
#IBOutlet weak var ibCollectionView: UICollectionView!
var cellArray:[customCollectionViewCell] = Array(repeating: customCollectionViewCell(), count: 6)
let displayedCellDimensions = CGSize(width: 343, height: 248)
//MARK: - Xcode-generated Methods
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Collection View Methods
//Place cells in collection view and change the cell size
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if collectionView.visibleCells.isEmpty {
for cell in 0...cellArray.count {
collectionView.addSubview(cellArray[cell])
return CGSize(width: 343, height: 248)
}
}
return CGSize(width: 343, height: 248)
}
//Register a new cell
func registerCell(_ collectionView: UICollectionView) {
for _ in 0...cellArray.count {
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return cellArray.count
}
...}
In your viewDidLoad() Try:
viewDidLoad() {
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
Add this to the top of your class:
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
You must use these functions in your ViewController class:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {}