collectionView reloaddata inside TableView - swift

I need to reloadData collectionView. Because I am append to array in function. I need to do reload data for this, but I get the error "Type of expression is ambiguous without more context". Data does not appear to be added because I did not reloadData. how can i use collectionView.reloadData? How can I reload data on TableView and CollectionView?
class denemeView: UIViewController, UITableViewDataSource, UITableViewDelegate {
var davetiyeKategori = [String]()
var davetiyeKatIsım = [String]()
var storedOffsets = [Int: CGFloat]()
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return kategoriIsımYeni[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return kategoriIsımYeni.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let tableViewCell = cell as? CategoryRow else { return }
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let tableViewCell = cell as? CategoryRow else { return }
storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
}
func collectionReloadData(){
DispatchQueue.main.async(execute: {
self.collectionView.reloadData()
})
}
override func viewDidLoad() {
super.viewDidLoad()
davetiyeKategoriBul()
}
#objc func davetiyeKategoriBul(){
if let baslik = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
for review in baslik {
if let soru_baslik = review["ISIM"] as? String {
let s = String(describing: soru_baslik)
self.kategoriIsımYeni.append(s)
DispatchQueue.main.async {
// self.tableViewKategoriler.reloadData()
}} }}
extension denemeView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return model[collectionView.tag].count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! anaSayfaCell
let rowValue = model[collectionView.tag][indexPath.item]
print("urlNew", rowValue)
let urlNew = URL(string: (rowValue))
cell.denemeImage.sd_setImage(with: urlNew)
// cell.backgroundColor = model[collectionView.tag][indexPath.item]
print("model[collectionView.tag][indexPath.item]", model[collectionView.tag][indexPath.item])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Collection view at row \(collectionView.tag) selected index path \(indexPath)")
}
}

Related

set image to imageview in uicollectionview that is in uitableviewcell xib

I have taken a UITableView and deque a UITableViewCell XIB and set data to a label in it, also I have UICollectionView in UITableViewCell XIB in which I have to set images in a UICollectionViewCell.
UIImageView is in UICollectionViewCell and respective UICollectionView is in UITableViewCell so how to set an image to that UIImageView?
also have tableview delegate function in one file
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.discoverData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveryTableViewCell", for: indexPath) as! discoveryTableViewCell
let data = discoverData[indexPath.row]
cell.messageLbl.text = (data["content"] as! String)
// This how normally image is set in tableview, how to do with collectionview
cell.userImage.pin_updateWithProgress = true
let riderImage = URL(string: (data["profile_pic"] as! String))
cell.userImage.pin_setImage(from: riderImage, placeholderImage: nil, completion: nil)
return cell
}
collection view delegate function in UITableViewCell.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numCell
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "discoverCell", for: indexPath as IndexPath) as! discoverCollectionViewCell
cell.postImage.backgroundColor = .cyan
return cell
}
Here is a picture of how it looks yellow box is UICollectionView and cyan color box is UIImageView.
In cellForRowAt indexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveryTableViewCell", for: indexPath) as! discoveryTableViewCell
if let data = discoverData[indexPath.row] as? [String: Any] {
cell.messageLbl.text = (data["content"] as! String)
cell.data = data
}
return cell
}
In your "discoveryTableViewCell" (It should be "DiscoveryTableViewCell") :
var data: [String: Any] {
didSet {
collectionView.reloadData()
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "discoverCell", for: indexPath as IndexPath) as! discoverCollectionViewCell
if let profilePic = data["profile_pic"] as? String {
let riderImage = URL(string: profilePic)
cell.postImage.pin_setImage(from: riderImage, placeholderImage: nil, completion: nil)
}
return cell
}
You should follow the proper style guide and naming conventions in Swift.
Please check this URL for better understanding:
https://github.com/raywenderlich/swift-style-guide

Change tableView Cells by choosing different cells from collectionView which is the Header of tableview

I have the collectionView as my tableview header. Now I need to change the cells of the tableView depending on the cell I choose from the collection view. How do I do this from didselect of the collectionview?
This is my tableview:
extension DeliveryTimeVC: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sortedTimeFrom.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print("Section \(indexPath.section), Row : \(indexPath.row)")
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.DeliveryTimeCell, for: indexPath) as! DeliveryTimeCell
cell.configureCell(timeFrom: sortedTimeFrom[indexPath.row], timeTo: sortedTimeTo[indexPath.row])
return cell
}
}
And this is my collectionView:
extension DeliveryTimeVC : UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sortedDates.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.DeliveryDateCell, for: indexPath) as! DeliveryDateCell
cell.configureCell(date: sortedDates[indexPath.row], day: sortedDay[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.DeliveryDateCell, for: indexPath) as! DeliveryDateCell
}
and this is how I call the header:
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableHeaderView = collectionView
tableView.tableFooterView = UIView()
}
here is my sortedTimeFrom:
var sortedTimeFrom: [Date] = {
let today = Date()
var sortedTime: [Date] = []
var calender = Calendar(identifier: .iso8601)
calender.locale = Locale(identifier: "en_US_POSIX")
let currentHour = calender.component(.hour, from: today)
(0...(24-currentHour)).forEach {
guard let newDate = calender.date(byAdding: .hour, value: $0, to: today),
calender.component(.hour, from: newDate) >= 10
&& calender.component(.hour, from: newDate) <= 22
&& calender.component(.hour, from: newDate) != 0
&& calender.component(.hour, from: newDate) >= (currentHour+3) else {
return
}
//convert date into desired format
sortedTime.append(newDate)
}
return sortedTime
}()
Disclaimer: typed in browser, not tested in Xcode.
Create a property inside DeliveryTimeVC:
var dataSource: [Date] = []
override func viewDidLoad() {
super.viewDidLoad()
dataSource = sortedTimeFrom
///... other stuff
}
Then, inside your tableView dataSource methods access that value:
extension DeliveryTimeVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.DeliveryTimeCell, for: indexPath) as! DeliveryTimeCell
cell.configureCell(timeFrom: dataSource[indexPath.row], timeTo: sortedTimeTo[indexPath.row]
return cell
}
}
Finally, inside didSelect do something like this:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dataSource = sortedTimeAgain
tableView.reloadData()
}

CollectionView Inside TableView

I have a CollectionView in TableViewController cell the tableViewcontains 3 sections each section is a different category. How I can pass different data in each section. Like Netflix app
In UICollectionViewController file
import UIKit
import Alamofire
class HomeViewController: UITableViewController, MovieDataDelegate {
let tableViewHeaderIdentifier = "FeaturedTableHeader"
var homePresenter : HomePresenter!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let headerNib = UINib(nibName: "FeaturedUITableViewHeaderView", bundle: nil)
tableView.register(headerNib, forHeaderFooterViewReuseIdentifier: tableViewHeaderIdentifier)
homePresenter = HomePresenter()
homePresenter.delegate = self
homePresenter.fetchData()
homePresenter.fetchImageData()
}
func arrayOfMoviesNames(names: [String]) {
//print(homePresenter.homeData.moviesNamesArray)
tableView.reloadData()
}
func arrayOfPosters(path: [String]) {
//print(homePresenter.homeData.posterPathsArray)
}
//MARK: - Home UI table
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "featuredCell", for: indexPath) as! FeaturedTableViewCell
cell.homeCollectionView.dataSource = self
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: tableViewHeaderIdentifier) as! FeaturedUITableViewHeaderView
switch section {
case 0:
headerView.isHidden = true
case 1:
headerView.catagoryLabel.text = "Popular Movies"
case 2:
headerView.catagoryLabel.text = "Celebs"
default:
headerView.catagoryLabel.text = "" as String
}
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 {
return 0
}
return 35
}
override func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return 12
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let tableViewCell = cell as? FeaturedTableViewCell else { return }
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
}
}
//MARK: - collectionView
extension HomeViewController : UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return homePresenter.homeData.moviesNamesArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "homeCollectionCell", for: indexPath) as! HomeCollectionViewCell
cell.posterImage.image = UIImage(named: "Aladdin")
cell.movieName.text = "coco"
return cell
}
}
In UITableViewCell file
import UIKit
class FeaturedTableViewCell: UITableViewCell {
#IBOutlet weak var homeCollectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let collectionNib = UINib(nibName: "HomeCollectionViewCell", bundle: nil)
homeCollectionView.register(collectionNib, forCellWithReuseIdentifier: "homeCollectionCell")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension FeaturedTableViewCell {
func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(_ dataSourceDelegate: D, forRow row: Int) {
homeCollectionView.delegate = dataSourceDelegate
homeCollectionView.dataSource = dataSourceDelegate
homeCollectionView.tag = row
homeCollectionView.reloadData()
}
}
screenshot of app
I want to show diffrent image and text for each section of tabelview
Create a struct Movie and create an array of tuple in the view controller. In tuple add a category title and an array of related movies. In table view data source methods use the main array and in collection view data source methods use the movies array from the corresponding tuple. Set the current tuple/section index as the collectionView tag. And get the appropriate movies array in the collection view data source methods.
//HomeViewController
class HomeViewController: UITableViewController {
struct Movie {
var name: String
var image: UIImage?
//other details
}
var movieDetails:[(title:String, movies:[Movie])] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(FeaturedCell.self, forCellReuseIdentifier: "FeaturedCell")
movieDetails = [(title: "MoviesDB", movies: [Movie(name: "a", image: UIImage(named: "a")),
Movie(name: "b", image: UIImage(named: "b")),
Movie(name: "c", image: UIImage(named: "c"))]),
(title: "Popular Movies", movies: [Movie(name: "d", image: UIImage(named: "d")),
Movie(name: "e", image: UIImage(named: "e")),
Movie(name: "f", image: UIImage(named: "f"))]),
(title: "Celebs", movies: [Movie(name: "g", image: UIImage(named: "g")),
Movie(name: "h", image: UIImage(named: "h")),
Movie(name: "i", image: UIImage(named: "i"))])]
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return movieDetails.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return movieDetails[section].title
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FeaturedCell") as? FeaturedCell ?? FeaturedCell(style: .default, reuseIdentifier: "FeaturedCell")
cell.collectionView.tag = indexPath.section
cell.collectionView.delegate = self
cell.collectionView.dataSource = self
return cell
}
}
extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return movieDetails[collectionView.tag].movies.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCell", for: indexPath) as? HomeCell ?? HomeCell()
let movie = movieDetails[collectionView.tag].movies[indexPath.item]
cell.posterImage.image = movie.image
cell.movieName.text = movie.name
return cell
}
}
//FeaturedCell
class FeaturedCell: UITableViewCell {
var collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.scrollDirection = .horizontal
}
collectionView.register(HomeCell.self, forCellWithReuseIdentifier: "HomeCell")
collectionView.translatesAutoresizingMaskIntoConstraints = false
addSubview(collectionView)
collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
}
//HomeCell
class HomeCell: UICollectionViewCell {
let posterImage = UIImageView()
let movieName = UILabel()
//...
}
Use both UITableView data source and UICollectionView data source methods.
Set 3 sections in UITableView with only one cell for every section.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Your cell with UICollectionView inside
let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_TABLE_VIEW_CELL_IDENTIFIER", for: indexPath)
// Set UICollectionViewDataSource, also add data source methods in your class, look at next code block
cell.collectionView.dataSource = self
return cell
}
// Header for each section,
func tableView(_ tableView: UITableView,
titleForHeaderInSection section: Int) -> String? {
if (section == 0) {
return nil
} else if (section == 1) {
return "Popular movies"
} else if (section == 2) {
return "Celebs"
}
}
// UICollectionViewDataSource methods
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1 // only one section for each UICOllectionView
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
// return here number of items in each UICollectionView
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YOUR_COLLECTION_CELL_IDENTIFIER", for: indexPath)
// set real data for each UICollectionCell here
cell.label = "COCO"
return cell
}
If you want to

Opening another screen by clicking on UICollectionViewCell

I have a screen that contains a UITableView and inside some UICollectionViews.
I need to click on UICollectionViewCell and open the next screen, and send some information to this new screen. But I can not.
According to my structure "follows" does not work. I need some help to find another way to do this.
Code: - TableViewCell
class CategoriasTableViewCell: UITableViewCell {
var db: Firestore!
var categoriasArray = [Categorias]()
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var labelTitleCategorias: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
collectionView.dataSource = self
collectionView.delegate = self
/*Firebase*/
let autenticacao = Auth.auth()
autenticacao.addStateDidChangeListener { (autenticacao, usuario) in
if let usuarioLogado = usuario {
} else {
//self.performSegue(withIdentifier: "checkEntrarSegue", sender: nil)
}
}
db = Firestore.firestore()
loadData()
}
func loadData() {
db.collection("Categories")
.addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}
self.categoriasArray = querySnapshot!.documents.flatMap({Categorias(dictionary: $0.data())})
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
}
Code - TableView
class TabHomeViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
let autenticacao = Auth.auth()
autenticacao.addStateDidChangeListener { (autenticacao, usuario) in
if usuario == nil {
self.performSegue(withIdentifier: "logoutAutomatico", sender: nil)
//....
}
}
}
}
extension TabHomeViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellSlide", for: indexPath) as! SlideTableViewCell
return cell
} else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellCategorias", for: indexPath) as! CategoriasTableViewCell
//cell.collectionView.reloadData()
return cell
} else if indexPath.row == 2{
let cell = tableView.dequeueReusableCell(withIdentifier: "cellRecomendacoes", for: indexPath) as! RecomendacoesTableViewCell
return cell
} else if indexPath.row == 3 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellPromocoes", for: indexPath) as! PromocoesTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellFamosos", for: indexPath) as! FamososTableViewCell
return cell
}
}
/*func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == 1 {
if let cell = cell as? CategoriasTableViewCell {
cell.collectionView.reloadData()
print("Atualizando Collection1")
}
}
}*/
}
extension TabHomeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return 215
case 1:
return 200
case 2:
return 300
case 3:
return 400
case 4:
return 500
default:
return UITableViewAutomaticDimension
}
}
}
//COLLECTION CATEGORIAS
extension CategoriasTableViewCell: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return categoriasArray.count //Int(Constant.totalItem)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//set the image URL
let urlBase = categoriasArray[indexPath.row].foto_horizontal
let imageUrl = URL(string: urlBase)!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BoxCollectionCategorias", for: indexPath) as! CellCategoriasCollectionViewCell
cell.labelNameCategoria.text = categoriasArray[indexPath.row].nome
cell.imageView.sd_setImage(with: imageUrl) { (image, erro, cache, url) in
// Here my code ...
}
return (cell)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Click... \(categoriasArray[indexPath.row].uid)")
// Here I detect the click on the UICollectionViewCell
}
}
extension CategoriasTableViewCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 130)
}
}
I'm using an extension CategoriasTableViewCell: UICollectionViewDataSource {}, to edit the UICollectionView data
You can just create delegate for your TableViewCell
protocol CategoriasTableViewCellDelegate : class {
func categoryTapped(_ cell: CategoriasTableViewCell, categoriasID:Int)
}
class CategoriasTableViewCell: UITableViewCell {
weak var delegate : CategoriasTableViewCellDelegate?
}
And In CategoriasTableViewCell Extention
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if delegate != nil {
delegate?.categoryTapped(self, categoriasID: categoriasArray[indexPath.row].uid)
}
print("Click... \(categoriasArray[indexPath.row].uid)")
// Here I detect the click on the UICollectionViewCell
}
At your TabHomeViewController set cell.delegate = self
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellSlide", for: indexPath) as! SlideTableViewCell
return cell
} else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellCategorias", for: indexPath) as! CategoriasTableViewCell
//cell.collectionView.reloadData()
cell.delegate = self
return cell
} else if indexPath.row == 2{
let cell = tableView.dequeueReusableCell(withIdentifier: "cellRecomendacoes", for: indexPath) as! RecomendacoesTableViewCell
return cell
} else if indexPath.row == 3 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellPromocoes", for: indexPath) as! PromocoesTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellFamosos", for: indexPath) as! FamososTableViewCell
return cell
}
}
// now you can get Data in TabHomeViewController
extension TabHomeViewController:CategoriasTableViewCellDelegate {
func categoryTapped(_ cell: CategoriasTableViewCell, categoriasID:Int){
}
}
You need to trigger a segue to reach the other view, or present your new view on top of the current view (which I don't recommend unless you know what you are doing).
To pass your information from one view to another you have several options :
pass it through the segue (one to one)
use protocols & delegates (one to one)
use events & observers (one to many)
use a third class responsible for holding the current data (one to many)

Index path of a collection view cell that is inside of a table view cell

I have a UICollectionView nested inside of a table view cell. How can I get the index path of the horizontal row of the collectionview cell? I tried to use
let index = cell.tag
print(index as Any)
to print which index was being selected not knowing that it will print a value of zero no matter what cell I select. I apologize that I am not experienced with collection views. Any help is much appreciated. Thanks.
You should design a protocol handling nested UIElement interactions. It makes your mind clearer and allocate better addresses
class ViewwithTable:UIViewController,UITableViewDataSource,collectionCell_delegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "temp", for: indexPath) as! NestedViewwithCollection
cell.delegate = self
return cell
}
func didPressed(indexPath: IndexPath) {
//the pressed index!
}
}
class NestedViewwithCollection:UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate{
var delegate:collectionCell_delegate?
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let del = delegate{
del.didPressed(indexPath: indexPath)
}
}
}
protocol collectionCell_delegate {
func didPressed(indexPath:IndexPath)
}
Use this code for tableView
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return model.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
return cell
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
guard let tableViewCell = cell as? TableViewCell else { return }
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
}
Collection View
extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource
{
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return model[collectionView.tag].count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
forIndexPath: indexPath)
cell.backgroundColor = model[collectionView.tag][indexPath.item]
return cell
}