collectionView numberOfItemsInSection in UITableviewCell - ios

I made one collectionView inside the tableView cell
I registered all delegates and protocols and in most cases everything works fine
the problem is that the collectionView must dynamically generate cells from the server response
I installed a counter on the top of the collection that shows how many cells there are (also dynamically updated)
if the collection is in the field of view when the screen is loaded, the cells are loaded
if it is necessary to complete the collection, it is empty, although the counter indicates the presence of elements.
I can not quite understand why. Code below
code form VC:
let realPfotoCell = tableView.dequeueReusableCell(withIdentifier:
"RealPhoto", for: indexPath)
as! RealPhotoCarInfoTableViewCell
realPfotoCell.delegate = self
realPfotoCell.model = self.rPhoto
if(self.rPhoto?.data != nil){
realPfotoCell.RPhotoCount.text = String(self.rPhoto.data!.count)
}
cell = realPfotoCell
cell.selectionStyle = UITableViewCell.SelectionStyle.none
}
code from tableViewCell:
var model: RealPhoto!
func setCollectionViewDataSourceDelegate(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate, forRow row: Int) {
MyCollection.delegate = self
MyCollection.dataSource = self
MyCollection.reloadData()
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
MyCollection.reloadData()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (self.model?.data?.count != nil){
print("Photos here")
print(self.model?.data!.count as Any)
} else {
print("No photos")
}
return self.model?.data?.count ?? 0
}

Please make sure the ReloadData() will be call when your server response will come.
//Server Response
MyCollection.delegate = self
MyCollection.dataSource = self
MyCollection.reloadData()

resolved
1st on tableview cell create this function:
func collectionReloadData(){
DispatchQueue.main.async(execute: {
self.collectionView.reloadData()
})
}
then call it from
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { ...
realPfotoCell.collectionReloadData()

Related

Cells of UICollectionsView in Xcode Not Appearing

I am developing an app and set up a UICollectionView. Below is the code for the view controller for where the UICollectionView is located in:
import UIKit
import Firebase
import FirebaseFirestoreSwift
import FirebaseFirestore
class scrollCollectionViewController: UICollectionViewController{
var tournaments = [String]()
#IBOutlet weak var collectionview: UICollectionView!
override func viewDidLoad() {
fetchTourneys()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Register cell classes
// Do any additional setup after loading the view.
}
func fetchTourneys() {
let db = Firestore.firestore()
db.collection("Tournaments").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.tournaments.append(document.documentID)
}
}
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return self.tournaments.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "tourneyIdentifier", for: indexPath) as! ScrollCollectionViewCell
cell.tournamentTitle.text = tournaments[indexPath.row]
print(cell.tournamentTitle.text)
// Configure the cell
return cell
}
// MARK: UICollectionViewDelegate
/*
// Uncomment this method to specify if the specified item should be highlighted during tracking
override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return true
}
*/
/*
// Uncomment this method to specify if the specified item should be selected
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return true
}
*/
/*
// Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item
override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
return false
}
override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
}
*/
}
The cells just dont end up showing up. After including some print statements, I noticed none of the override funcs for numberOfSections or the collection views seem to be running. What could be the issue for why these are not running, and why the cells are not showing up?
you need to return self.tournaments.count in numberOfItemsInSection
func fetchTourneys() {
let db = Firestore.firestore()
db.collection("Tournaments").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.tournaments.append(document.documentID)
}
self.collectionview.reloadData()
}
}
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return self.tournaments.count
}
Please move the fetchTourneys() after super.viewDidLoad(). Also, you need to ensure the cell identifier is set up correctly and registered with your collectionView
private let reuseIdentifier = "tourneyIdentifier"
class scrollCollectionViewController: UICollectionViewController {
var tournaments = [String]()
#IBOutlet weak var collectionview: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
self.collectionview!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
fetchTourneys()
}
then, when the cells are being created, re-use the reuseIdentifier
.dequeueReusableCell(withReuseIdentifier: reuseIdentifier
Also, within your Firebase function, ensure you tell the collectionView to update after you've populated the dataSource
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.tournaments.append(document.documentID)
}
self.collectionview.reloadData()
}
Also you said
I noticed none of the override funcs for numberOfSections or the
collection views seem to be running
That would indicate your UICollectionView doesn't know this code is it's viewController. Ensure you've set that up in XCode Inspector. Generally speaking, Classes and Structs should start with a capital letter, vars are lowercased
You have to call reloadData on collectionview once the fetchTourneys is complete.
func fetchTourneys() {
let db = Firestore.firestore()
db.collection("Tournaments").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.tournaments.append(document.documentID)
}
self.collectionview.reloadData()
}
}
}
You need to set collectionview datasource and delegate to self in viewDidLoad
put delegate = self and dataSource = self in viewDidLoad
Everyone's answers pointed out errors in the code which moved it in the right direction. But it still did not end up showing the cells. I printed each cell, and noticed that there was a parameter that made them all hidden. I have no idea what caused that. But I added the following code:
cell.isHidden = false
And it worked out great!

When I go back to the page, changing number and cell datas of the TableView

I am using nested tableview. The main tableview lists the file categories. Child tableview listing the files. I open the files with safari. The child tableview is listed incorrectly when I go back to the page after opening the file. How can i solve this problem? Android sdk have "onActivityResult" method. Does iOS have a similar function? Thanks.
ViewController
import UIKit
class ProductDetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
var bundleProductModel:ProductModel? = ProductModel.init()
var lastFileCatIndex:Int = 0
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// If tableview is file category table.
if (tableView.tag == 100){
return bundleProductModel!.fileCategoryModels.count
} else /* Table view is file tableview. */ {
//self.lastFileIndex = self.lastFileIndex + 1
return (bundleProductModel?.fileCategoryModels[self.lastFileCatIndex].files.count)!
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if (tableView.tag == 100){
// Define cell for file category.
let cell = tableView.dequeueReusableCell(withIdentifier: "FileCategoryTableViewCell") as! FileCategoryTableViewCell
// Set file category cell height.
cell.frame.size.height = CGFloat(((bundleProductModel?.fileCategoryModels[indexPath.row].files.count)! * 44) + 42)
// cell row height
tableView.rowHeight = CGFloat(((bundleProductModel?.fileCategoryModels[indexPath.row].files.count)! * 44) + 42)
// Control bound
if (self.lastFileCatIndex <= indexPath.row){
// Index.
self.lastFileCatIndex = indexPath.row
// File category name.
cell.lblFileCatNme.text = " \(bundleProductModel?.fileCategoryModels[indexPath.row].file_category_name ?? "Unknow") "
}
return cell
} else {
// Define cell for files.
let cell = tableView.dequeueReusableCell(withIdentifier: "FileTableViewCell") as! FileTableViewCell
if ((bundleProductModel?.fileCategoryModels[self.lastFileCatIndex].files.count)! > indexPath.row){
// Set file model to file cell.
cell.setFile(fileItem: (self.bundleProductModel?.fileCategoryModels[self.lastFileCatIndex].files[indexPath.row])!)
// file cell delegate
cell.delegate = self
} else {
cell.lblFileName.text = "unknow"
}
return cell
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ProductDetailViewController:FileCellDelegate{
func didClickDownload(downloadLink: String, button: UIButton) {
if let url = URL(string: downloadLink) {
UIApplication.shared.open(url)
}
}
}
A very easy workaround on iOS would be to override viewWillAppear and call reloadData() like so:
override func viewWillAppear() {
super.viewWillAppear()
tableView.reloadData()
}
This will update your table everytime your view reappears.
SOLVED
Problem is lastFileCategoryIndex variable. Ex: final value is four. When I come back to the page; listing relative to fourth index. I define child tableview in main tableview cell and solved.
FileCategoryTableViewCell
class FileCategoryTableViewCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
// General Objects
var fileCategoryModel:FileCategoryModel = FileCategoryModel.init()
// Cell Ui Objects
#IBOutlet weak var lblFileCatNme: UILabel!
#IBOutlet weak var fileTableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fileCategoryModel.files.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = fileTableView.dequeueReusableCell(withIdentifier: "FileTableViewCell") as! FileTableViewCell
cell.lblFileName.text = "Ex File..."
return cell
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
// Set category model.
func setFileCategory(fileCategoryModel:FileCategoryModel){
self.fileCategoryModel = fileCategoryModel
self.fileTableView.dataSource = self
self.fileTableView.delegate = self
}
}

Not using reusable cell in UITableView with CollectionView in each cell

I have a UITableView and in its prototype cell have a UICollectionView.
MainViewController is delegate for UITableView and
MyTableViewCell class is delegate for UICollectionView.
On updating each TableViewCell contents I call cell.reloadData() to make the collectionView inside the cell reloads its contents.
When I use reusable cells, as each cell appears, it has contents of the last cell disappeared!. Then it loads the correct contents from a URL.
I'll have 5 to 10 UITableViewCells at most. So I decided not to use reusable cells for UITableView.
I changed the cell creation line in tableView method to this:
let cell = MyTableViewCell(style: .default, reuseIdentifier:nil)
Then I got an error in MyTableViewCell class (which is delegate for UICollectionView), in this function:
override func layoutSubviews() {
myCollectionView.dataSource = self
}
EXC_BAD_INSTRUCTION CODE(code=EXC_I386_INVOP, subcode=0x0)
fatal error: unexpectedly found nil while unwrapping an Optional value
MyTableViewCell.swift
import UIKit
import Kingfisher
import Alamofire
class MyTableViewCell: UITableViewCell, UICollectionViewDataSource {
struct const {
struct api_url {
static let category_index = "http://example.com/api/get_category_index/";
static let category_posts = "http://example.com/api/get_category_posts/?category_id=";
}
}
#IBOutlet weak var categoryCollectionView: UICollectionView!
var category : IKCategory?
var posts : [IKPost] = []
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
if category != nil {
self.updateData()
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func layoutSubviews() {
categoryCollectionView.dataSource = self
}
func updateData() {
if let id = category?.id! {
let url = const.api_url.category_posts + "\(id)"
Alamofire.request(url).responseObject { (response: DataResponse<IKPostResponse>) in
if let postResponse = response.result.value {
if let posts = postResponse.posts {
self.posts = posts
self.categoryCollectionView.reloadData()
}
}
}
}
}
internal func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "postCell", for: indexPath as IndexPath) as! MyCollectionViewCell
let post = self.posts[indexPath.item]
cell.postThumb.kf.setImage(with: URL(string: post.thumbnail!))
cell.postTitle.text = post.title
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//You would get something like "model.count" here. It would depend on your data source
return self.posts.count
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
}
MainViewController.swift
import UIKit
import Alamofire
class MainViewController: UITableViewController {
struct const {
struct api_url {
static let category_index = "http://example.com/api/get_category_index/";
static let category_posts = "http://example.com/api/get_category_posts/?category_id=";
}
}
var categories : [IKCategory] = []
override func viewDidLoad() {
super.viewDidLoad()
self.updateData()
}
func updateData() {
Alamofire.request(const.api_url.category_index).responseObject { (response: DataResponse<IKCategoryResponse>) in
if let categoryResponse = response.result.value {
if let categories = categoryResponse.categories {
self.categories = categories
self.tableView.reloadData()
}
}
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return self.categories.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.categories[section].title
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: "CollectionHolderTableViewCell") as! MyTableViewCell
let cell = MyTableViewCell(style: .default, reuseIdentifier:nil)
cell.category = self.categories[indexPath.section]
cell.updateData()
return cell
}
}
MyCollectionViewCell.swift
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var postThumb: UIImageView!
#IBOutlet weak var postTitle: UILabel!
var category : IKCategory?
}
Why not reusing cells caused this? Why am I doing wrong?
There are a few things to do that should get you up to speed.
First, uncomment the line that uses reusable cells and remove the line of code that creates the non-reusable cells. It is safe to use reusable cells here.
Second, in MyTableViewCell, set the dataSource for the collection view right after the super.awakeFromNib() call. You only need to set the dataSource once, but layoutSubviews() will potentially get called multiple times. It's not the right place to set the dataSource for your needs.
override func awakeFromNib() {
super.awakeFromNib()
categoryCollectionView.dataSource = self
}
I have removed the call to updateData() from awakeFromNib(), as you are already calling it at cell creation. You can also delete the layoutSubviews() override, but as a general rule, you should be careful to call super.layoutSubviews() when overriding it.
Lastly, the reason the posts seemed to re-appear in the wrong cells is that the posts array wasn't being emptied as the cells were reused. To fix this issue, add the following method to MyTableViewCell:
func resetCollectionView {
guard !posts.isEmpty else { return }
posts = []
categoryCollectionView.reloadData()
}
This method empties the array and reloads your collection view. Since there are no posts in the array now, the collection view will be empty until you call updateData again. Last step is to call that function in the cell's prepareForReuse method. Add the following to MyTableViewCell:
override func prepareForReuse() {
super.prepareForReuse()
resetCollectionView()
}
Let me know how it goes!

Closure block not reloading table on second time swift3

I have a table with button and label .When I tap on button it gets highlighted .So I have 5 rows each with button and label and when I tap on every button they are highlighted.Now on remaining view apart from table I have cancel button when I tap on it I want all the selected rows to reload again.My code works fine for the first execution .Like I selected all 5 button then tap on cancel button all rows are reloaded.But when I select button in table row again and tap on cancel nothing happens.Call is going inside my closure function I can see the correct index printed for reloading but nothing happens.My code is this-:
Cell Custom class-:
import UIKit
class TestingControllerCellTableViewCell: UITableViewCell {
#IBOutlet weak var TableButton: UIButton!
#IBOutlet weak var TableMenu: UILabel!
var TableButtonCallBack : (()->())?
override func awakeFromNib() {
super.awakeFromNib()
ButtonLayout()
// Initialization code
}
func ButtonLayout()
{
TableButton.layer.cornerRadius = 12.5
TableButton.layer.borderWidth = 1.0
TableButton.layer.borderColor = UIColor.gray.cgColor
self.selectionStyle = UITableViewCellSelectionStyle.none
}
#IBAction func filterTableRadioButtonAction(_ sender: UIButton) {
TableButtonCallBack?()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
controller class-:
import UIKit
class filterControllerViewController: UIViewController {
#IBOutlet weak var TableViewController: UITableView!
fileprivate var ButtonSelectedIndex = [[Int]]()
fileprivate var cancelDataItemSelectedCallBack : ((Int)->())? = nil
override func viewDidLoad() {
super.viewDidLoad()
filterTableViewSetUp()
// Do any additional setup after loading the view.
}
// CANCEL ACTION
#IBAction func cancelDataItemSelected(_ sender: UIButton) {
for sectionIndex in 0..<filterRadioButtonSelectedIndex.count
{
for valueIndex in 0..<ButtonSelectedIndex[sectionIndex].count
{
cancelDataItemSelectedCallBack!(ButtonSelectedIndex[sectionIndex][valueIndex])
}
}
ButtonSelectedIndex.removeAll()
}
func TableViewSetUp()
{
TableViewController.delegate = self
TableViewController.dataSource = self
TableViewController.backgroundColor = UIColor.green
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
}
extension filterControllerViewController:UITableViewDataSource,UITableViewDelegate
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let filterCell = tableView.dequeueReusableCell(withIdentifier: "filterCell", for: indexPath) as! FilterControllerCellTableViewCell
filterCell.filterTableRadioButtonCallBack = {
filterCell.TableButton.backgroundColor = UIColor.blue
self.ButtonSelectedIndex.append([indexPath.row])
}
// THIS cancelDataItemSelectedCallBack CALLED FIRST TIME AND RELOAD TABLE EVEN GETS CALLED SECOND TIME SHOWS CORRECT INDEX BUT TABLE BUTTONS STLL REMAIN HIGHLIGHTED
self.cancelDataItemSelectedCallBack = { data in
let indexPath = IndexPath(item: data, section: indexPath.section)
print(indexPath)
self.TableViewController.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
}
return filterCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 40.0
}
}
I know I am missing something but not getting it.Please help
print indexPath within self.cancelDataItemSelectedCallBack gives me this output which is correct.But it works only one time.
[0, 2]
[0, 3]
You have to reload the UI on the main thread like this:
self.cancelDataItemSelectedCallBack = { data in
OperationQueue.main.addOperation {
let indexPath = IndexPath(item: data, section: indexPath.section)
self.TableViewController.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
}
}

iOS swift UIButton in TableView Cell

I have a tableView with custom cell. in my custom cell I have a like button. for like Button I wrote a function to change state from .normal to .selected like this:
FeedViewCell
class FeedViewCell: UITableViewCell {
#IBOutlet weak var likeButton: UIButton!
var likes : Bool {
get {
return UserDefaults.standard.bool(forKey: "likes")
}
set {
UserDefaults.standard.set(newValue, forKey: "likes")
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.likeButton.setImage(UIImage(named: "like-btn-active"), for: .selected)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func likeBtnTouch(_ sender: AnyObject) {
print("press")
// toggle the likes state
self.likes = !self.likeButton.isSelected
// set the likes button accordingly
self.likeButton.isSelected = self.likes
}
}
FeedViewController :
class FeedViewController: UIViewController {
#IBOutlet var feedTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Register Cell Identifier
let feedNib = UINib(nibName: "FeedViewCell", bundle: nil)
self.feedTableView.register(feedNib, forCellReuseIdentifier: "FeedCell")
}
func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.feeds.count
}
func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FeedCell", for: indexPath) as! FeedViewCell
return cell
}
}
But my problem is when I tap like button in cell with indexPath.row 0 the state of button in cell with indexPath.row 3 change state too.
where is my mistake?
thanks
You didn't post all your code, but I can tell you that for this to work the #IBAction func likeBtnTouch(_ sender: AnyObject) { } definition must be inside the FeedViewCell class definition to make it unique to a particular instance of the cell.
As a rule of thumb, I normally ensure that all the UI elements inside my cell are populated in cellForRowAtIndexPath when using dequeued cells. Also it should be set from an external source. I.o.w not from a property inside the cell. Dequeuing cells reuse them, and if not setup properly, it might have some leftovers from another cell.
For example, inside cellForRowAtIndexPath:
self.likeButton.isSelected = likeData[indexPath.row]

Resources