Displaying xib from collectionView embedded in tableView - ios

I am trying to display a xib of a collectionViewCell from the tableViewCell (so I can do both horizontal and vertical scrolling while having categories per row). It seems that the register of the xib is where the issue is coming into play as it will not register it properly from the proper place? tableView cannot be registering it since it fails when I tried to do so, I have registered it in the collectionView but where it wont crash but nothing displays. Maybe this isn't the best way to do it - but what would be a good alternative to implement a spaced out horizontal scrolling and vertical scrolling? Here is my source code so far
import UIKit
class DiscoverViewController: UIViewController {
#IBOutlet weak var discoverTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension DiscoverViewController: UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
collectionView.register(UINib(nibName: "DiscoverCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "DiscoverCollectionViewCell")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DiscoverCollectionViewCell", for: indexPath) as! DiscoverCollectionViewCell
cell.authorLabel.text = "this"
cell.coverImage.image = #imageLiteral(resourceName: "discover")
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = discoverTableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as! CategoryTableViewCell
return cell
}
}

figured it out, the delegate and datasource had to be set to the TableView cell file as well as registering the xib on the TV with an instance of the CV on there. thanks to #Daniel for a point in the right direction.

Related

Find which collection view cell is linked to my table view

I'm looking for your help for my association between a tableview and a collection view.
I've got a CollectionView with 6 horizontal scrollable cells.
In each cell, I would like to put a table view.
For each tableView, I need to know in which cell I am to put my wanted data.
Actually, I make my code work for displaying tableView inside the cells but I'm blocked for finding in which collection view cell I am.
BTW, my Meal_vc_cell controller is actually Empty, it just has a simple outlet. Nothing else.
Here is my code
class TrainFoodPlanViewController: BaseViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UITableViewDataSource, UITableViewDelegate {
let train_meals_list: [String] = ["breakfast", "snack_1", "pre_intra_post", "lunch", "snack_2", "diner"]
#IBOutlet weak var trainCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Food Plan"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return train_meals_list.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collection_cell", for: indexPath) as! Meal_vc_cell
cell.meal_number.text = train_meals_list[indexPath.row]
return cell
}
}
Here is what I'm trying to do
There are a number of ways this can be achieved. My recommendation is to subclass UITableView and add a parentCollectionViewIndexPath property
class MyCustomTableView: UITableView {
var parentCollectionViewIndexPath: IndexPath?
}
I'm assuming Meal_vc_cell has an outlet to the relevant tableView. Change that tableView's type to MyCustomTableView
class Meal_vc_cell: UITableViewCell {
#IBOutlet weak var tableView: MyCustomTableView
}
Note: If you're using storyboard, don't forget to update the tableView's class in storyboard as well
Now, just set parentCollectionViewIndexPath in the collectionView's cellForItemAt method
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collection_cell", for: indexPath) as! Meal_vc_cell
cell.tableView.parentCollectionViewIndexPath = indexPath
return cell
}

UICollectionView not rendering cells - no code only storyboard

I am experimenting with UICollectionView and am only using Storyboard - no code at all. I set the number of items to 3 and gave each cell a different color and reuse identifier in the storyboard. Yet the CollectionView (pinkish background) is shown but no cells are shown. What am I missing?
Thanks in advance
-SR
Short Answer
UICollectionView doesn't support static content layouts.
Discussion
But there is a way to simulate it through code. I recommend this great article.
You don't have any code in your ViewController.swift. You can add something like this:
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
var menuItems = ["Aap","Koe","Vis","Paard", "Leeuw", "Varken"]
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return menuItems.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if let c = cell as? AangepasteCollectionViewCell {
c.cellLabel.text = menuItems[indexPath.row].capitalized
}
return cell
}
}
For this example you have to give the collection cell the name cell in the atribute inspector

Table view inside of a collection view

I have a collection view, and each collection view cell will have a table view which will have different data for each collection view cell. The collection view is done using a storyboard and works fine, but I can not seem to get a UITableView to work inside of it. The Collection view code is below and any help is appreciated. Ideally a technique that allows me to use storyboard to customise the tableview cell, and I am using Swift 4.
extension StoryboardViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt
indexPath: IndexPath) {
print("Selected Cell #\(indexPath.row)")
}
}
extension StoryboardViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 6
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: "CollectionViewCell"), for: indexPath) as! StoryboardCollectionViewCell
cell.label.text = "Cell #\(indexPath.row)"
return cell
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("Current centered index: \(String(describing: centeredCollectionViewFlowLayout.currentCenteredPage ?? nil))")
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
print("Current centered index: \(String(describing: centeredCollectionViewFlowLayout.currentCenteredPage ?? nil))")
}
}
And I want to put a table view (list) inside of it like so:
UICollectionViewCell class that is being used should conform to UITableViewDelegate and UITableViewDataSource protocols that will initialize the cells in the table view
Your UICollectionViewCell Class should confirm to Protocols, UITableViewDelegate and UITableViewDataSource
import UIKit
class CollectionViewCell: UICollectionViewCell,UITableViewDelegate,UITableViewDataSource {
//MARK: TableViewDelegateAndDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//Configure your cell here
return UITableViewCell()
}
}
Finally don't forget to assign TableView DataSource and Delegate in your storyboard

How to change the cell height after putting a collection view into a table view

I'm trying to put some images with horizontal scrolling in a tableview cell, so I use a collectionview, I put it into the cell, and everything works except the cell height. I've chosen the cell height to custom in storyboard, and changed the cell height with code too, but it still doesn't work. I'm a rookie, I can't find where the problem is, please help me, thank you guys!
1.I want to change the cell height
2.Stroyboard
class HomePageTableViewController: UITableViewController {
var ImageArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
ImageArray = ["Calendar.png","Calendar.png","Calendar.png","Calendar.png","Calendar.png"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ImageArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BannerCell") as! BannerTableViewCell
return cell
}
override func viewWillAppear(_ animated: Bool) {
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
}
}
extension HomePageTableViewController: UICollectionViewDelegate,
UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return ImageArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
-> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BannerCollection", for: indexPath) as! BannerCollectionCollectionViewCell
cell.BannerImage.image = UIImage(named: ImageArray[indexPath.row])
return cell
}
}
You probably need to set the collectionviewcell size such as the following:
extension HomePageTableViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// Return the cell size
let cellSize = CGSize(width: collectionView.bounds.width, height: collectionView.bounds.width * (ratioToUse))
return cellSize
}
}
I've done something similar where I'm using a collectionview to scroll horizontally but I'm using the full width for each cell and calculating the aspectratio. However, you'll need to modify this for the size you want.
I had to do some tricks elsewhere to size the collectionview itself as well.
I would try this first then, if you're still having problems, post an image of what it looks like.
Update #2:
If you are using AutoLayout, you shouldn't need to do this but you can set the height yourself using the following:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
<#code#>
}
Update #3:
I just some testing with this. You should put a height constraint on your collectionview and that should make the tableviewcell resize appropriately. You shouldn't need "heightForRowAt" as I mentioned above. AutoLayout should handle this for you.
Try to change the content mode of the UIImageView to aspect fit. It might work.

Put UICollectionViewCell into UICollectionView

I am using LBTAComponents pod
this is a pod that makes easier to work with UICollectionView
without any need to register anything and provides a super simple anchoring system ... and in the first project I've got two days ago I decided to use this framework
but now I have a problem in one of uicollectionviewCells I need another collectionview that I can fill with items then I need it to be scrollable horizontally
import LBTAComponents
import UIKit
class ProductCell: DatasourceCell {
let cellId = "cellid"
let collectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .black
return cv
}()
override func setupViews() {
super.setupViews()
ProductCell.addSubview(collectionView)
collectionView.frame = frame
collectionView.register(UICollectionView.self, forCellWithReuseIdentifier: cellId)
collectionView.dataSource = self
}
}
extension ProductCell : UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
cell.backgroundColor = .white
return cell
}
}
datasourceCell is equal to UICollectionViewCell in this pod.
and now I am getting this ERROR :
instance member 'addsubview' cannot be used on type uiview did you use the value of this type instead?
could you please help me?
I tried to use self.addSubview(collectionView)
but I got another error enter image description here
You can simply use a UITableView with custom UITableViewCells containing a UICollectionView.
Example:
1. View Hierarchy
2. UIViewController containing UITableView
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return tableView.dequeueReusableCell(withIdentifier: "tcell", for: indexPath) as! TableCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.row == 0
{
return 120
}
else
{
return 150
}
}
}
3. Custom UITableViewCell containing UICollectionView
class TableCell: UITableViewCell, UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 3
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
return collectionView.dequeueReusableCell(withReuseIdentifier: "ccell", for: indexPath)
}
}
4. Output Screenshot
addsubview is an instance method, not a class method. So you should use:
self.addSubview(collectionView)
instead of:
ProductCell.addSubview(collectionView)

Resources