Populate items in tableView cell from a class model error? - ios

I have the following class model for the items. I am displaying itemsName,itemprice in sections. And Addonname and AdddonPrice in cell based on the index.. the number of sections and the number of cells are coming correctly from the class modal. sections data are also working fine. The problem is to display addon data into customTableCell.
class Cart{
var itemID:AnyObject?
var itemName:AnyObject?
var itemPrice:AnyObject?
var cartAddon:[AnyObject?]
init(itemID:AnyObject?,itemName:AnyObject?,itemPrice:AnyObject?,cartAddon:[AnyObject?]){
self.itemID = itemID
self.itemName = itemName
self.itemPrice = itemPrice
self.cartAddon = cartAddon
}
}
class CartAddon {
var addonID:Int?
var addonName:String?
var addonPrice:Double?
init(addonID:Int?,addonName:String?, addonPrice:Double?){
self.addonID = addonID
self.addonName = addonName
self.addonPrice = addonPrice
}
}
Tableview code
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return cartArray.count
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableCellWithIdentifier("cartheadercell") as! cartHeaderCell
header.ItemnameLbl.text = cartArray[section].itemName as? String
header.ItemPriceLbl.text = (cartArray[section].itemPrice as! String)
return header
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cartArray[section].cartAddon.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 30
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cartcell", forIndexPath: indexPath) as! AddonCell
//error in this part
let cart: Cart = cartArray[indexPath.row].cartAddon[indexPath.row]
if let name = cart.cartAddon[indexPath.row]!["AddonName"]{
cell.AddonNameLbl.text = (name as! String)
}
cell.AddonPriceLbl.text = "£ 0.0"
return cell
}
The data is coming in this form which I have to display is:
Optional(9 Inch Thin & Crispy Margarita)
Optional(£3.40)
Optional(1749)
[Optional(Chicos_Pizza.CartAddon), Optional(Chicos_Pizza.CartAddon), Optional(Chicos_Pizza.CartAddon), Optional(Chicos_Pizza.CartAddon)]

The problem is you need to use indexPath.section to access the Cart object from array not indexParh.row, so change your cellForRowAtIndexPath code like this.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cartcell", forIndexPath: indexPath) as! AddonCell
if let cartAddon = cartArray[indexPath.section].cartAddon[indexPath.row] as? CartAddon, let name = cartAddon.addonName {
cell.AddonNameLbl.text = name
}
else {
cell.AddonNameLbl.text = "Set here some default value or blank string"
}
cell.AddonPriceLbl.text = "£ 0.0"
return cell
}

Related

UITableView indexPath.row not increasing

I am loading data into a UITableView. The first load happens properly for the first 10 cells in
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}
the indexPath.row increments properly and loads the data into the proper cells from the data source. I then implemented a load more when the bottom of the table is reached. Now func tableView is called but it is stuck at indexPath.row = 9. I have implemented a checker in
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
And it appears that the proper number of rows has been added.
Edit: I having issue with the my second uitableview (there are two in this scene) The checker is a print statement that is called and returns the proper uitableView and this happens before the tableView gets stuck at the same value.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.table {
return users2.count
}
else {
print("married barry", tableFeedCount)
return tableFeedCount
}
}
Try following:
Declare boolean
let boolNotMoreData : Bool = true
Append new data to your data source
let arrResponse: [Any]? = (responseObject["news"] as? [Any])
if arrResponse?.count == 0{
boolNotMoreData = false;
}
for dictResponse in arrResponse as! [[String: Any]] {
self.arrDataSource.append(NewsClass(responseDict: dictResponse))
}
self.tblViewNews?.reloadData()
Now fetch new data
private func tableView(_ tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == arrNews.count - 1 {
if boolNotMoreData {
currentPage += 1
getYourData()
}
}
}
This worked Successfully
#IBOutlet weak var Submitted: UITableView!
#IBOutlet weak var ViewAssigenment: UITableView!
var Arrayone:[String] = []
var ArrayTwo:[String] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if tableView == self.ViewAssigenment
{
count = Arrayone.count
}
else if tableView == self.Submitted
{
count = ArrayTwo.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if tableView == self.ViewAssigenment
{
let cell = tableView.dequeueReusableCell(withIdentifier: "ViewCell") as!
ViewAssigenmentTableViewCell
let obj =Arrayone[indexPath.row]
cell.lblTitle.text = obj.AssTitle
return cell
}
else
{
let cell1 = tableView.dequeueReusableCell(withIdentifier: "Submittcell") as! SubmittedAssigenmentTableViewCell
let obj2 = ArrayTwo[indexPath.row]
cell1.lbltitle.text = obj2.AssTitle
return cell1
}
}

Adding two Custom cells in tableView

I have a tableView on mainStoryboard with two custom cells.
I would like to set two more cells at different row.
However When I implemented the code the added cells replaces original cells. (Custom cell of "Basic grammar3" and "Basic grammar5" are disappearing.)
I was trying to find the answer but could not find out.
I have image and code added below.
import UIKit
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tblStoryList: UITableView!
var array = PLIST.shared.mainArray
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.array.count + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 || indexPath.row == 3 || indexPath.row == 5 {
let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
cell.headerTitle.text = indexPath.row == 0 ? "First Stage" : indexPath.row == 3 ? "Second Stage" : "Third Stage"
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "StoryTableviewCell", for: indexPath) as! StoryTableviewCell
//making plist file
let dict = self.array[indexPath.row - 1]
let title = dict["title"] as! String
let imageName = dict["image"] as! String
let temp = dict["phrases"] as! [String:Any]
let arr = temp["array"] as! [[String:Any]]
let detail = "progress \(arr.count)/\(arr.count)"
//property to plist file をつなぐ
cell.imgIcon.image = UIImage.init(named: imageName)
cell.lblTitle.text = title
cell.lblSubtitle.text = detail
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
return
}
tableView.deselectRow(at: indexPath as IndexPath, animated:true)
if indexPath.row == 3 {
return
}
tableView.deselectRow(at: indexPath as IndexPath, animated:true)
if indexPath.row == 5 {
return
}
tableView.deselectRow(at: indexPath as IndexPath, animated:true)
let messagesVc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
messagesVc.object = self.array[indexPath.row - 1]
self.navigationController?.show(messagesVc, sender: self)
}
You could use sections for your table view. Now, you are returning 1 in your numberOfSections function. And it is creating only one section. If you want to use headers, you can use sections for your need. And also you can fill your table view cells with multidimendional arrays. For example:
For adjusting your section headers:
let lessonTitles = ["First Stage", "Second Stage"]
Titles for sections:
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section < lessonTitles.count {
return lessonTitles [section]
}
return nil
}
For adjusting your sections and rows:
let lessons = [["Basic Grammar 1", "Basic Grammar 2"], ["Basic Grammar 3", "Basic Grammar 4"]]
Number of sections function should be:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return lessons.count
}
Number of rows in section should be:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lessons[section].count
}
And creating your cells is like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellText = data[indexPath.section][indexPath.row]
...
}
Try like this...
func numberOfSections(in tableView: UITableView) -> Int
{
return numberOfStages
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return numberOfRowsInCurrentStage
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
return customizedCell
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
{
return requiredHeight
}
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
{
return stageCountView
}
You can use viewForHeaderInSection if you want to show stage count on top.
edit: The comment by raki is the much better solution (use headers). I leave this here in case you want something closer to your existing implementation.
You have to change your numbering scheme in order to insert these additional rows (and not replace existing rows). So you might want to adjust the row for the "normal" elements like this:
func adjustRow(_ row: Int) -> Int {
if row < 3 {
return row
} else if row < 5 {
return row+1
} else {
return row+2
}
}

UITableView not showing in order SWIFT

having some issue with tableview. The JSon content is in the right order but when i update the table thats when the problem starts. This is how i update the table:
var cats = [Categories]()
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
cats.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "CategoryTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CategoryTableViewCell
print(cats[indexPath.row].categoryName)
cell.nameLabel.text = cats[indexPath.row].categoryName
cell.subNameLabel.text = cats[indexPath.row].appShortDesc
return cell
}
When i print the JSon it shows the correct order just the tableview keeps doing what it feels like.

Creating sections with headers with two dynamic tableviewcells in Swift

I have a table view with two cells, "electionInfo" and "candidates". Candidates returns an array of the candidates, while electionInfo gives a single text body (so just one cell). I'd like to divide them into two sections with their respective headers. Right now, it gives me one header for both cells. How do I fix it?
Thanks!!
My code...
#IBOutlet weak var table: UITableView!
var info: [PFObject] = []
var items: [PFObject] = []
let titles = ["Election Info", "Candidates"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count + 1
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.items.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return titles[section]
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == self.items.count {
let cell = table.dequeueReusableCellWithIdentifier("candidateCell") as! CandidateTableViewCell
let candidate = items[indexPath.row]
cell.candidateImage.file = candidate["image"] as! PFFile
cell.candidateImage.loadInBackground()
cell.candidateName?.text = candidate["name"] as! String
cell.candidateParty?.text = candidate["partyAffiliation"] as! String
return cell
} else {
let cell = table.dequeueReusableCellWithIdentifier("electionCell") as! ElectionInfoTableViewCell
cell.electionInfo.text = "hey there"
}
}
}
internal func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2 //or the number of sections you have
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = UITableViewCell()
if indexPath.section == 0 {
let candidateCell = table.dequeueReusableCellWithIdentifier("candidateCell") as! CandidateTableViewCell
let candidate = items[indexPath.row]
cell.candidateImage.file = candidate["image"] as! PFFile
cell.candidateImage.loadInBackground()
cell.candidateName?.text = candidate["name"] as! String
cell.candidateParty?.text = candidate["partyAffiliation"] as! String
return candidateCell
} if indexPath.section == 1 {
let electionCell = table.dequeueReusableCellWithIdentifier("electionCell") as! ElectionInfoTableViewCell
cell.electionInfo.text = "hey there"
return electionCell
}
return cell
}
then you have also to change your numberOfRowsInSection
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if section == 0 {
return self.items.count
}
if section == 1 {
return self.items.count // or the number of rows you have in that section
}
}
A section and a cell is different thing in tableview. Right now your code gives you section instead of cell because you return self.items.count + 1 in numberOfSectionsInTableView. A fix for this;
Since your tableview should contain two section only you must return 2 or titles.count in numberOfSectionsInTableView
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.titles.count
}
Next return corresponding array count in numberOfRowsInSection
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return self.info.count
}else{
return self.items.count
}
}
And finally in cell for row at index path return cell based on a section:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 1 {
let cell = table.dequeueReusableCellWithIdentifier("candidateCell") as! CandidateTableViewCell
let candidate = items[indexPath.row]
cell.candidateImage.file = candidate["image"] as! PFFile
cell.candidateImage.loadInBackground()
cell.candidateName?.text = candidate["name"] as! String
cell.candidateParty?.text = candidate["partyAffiliation"] as! String
return cell
} else {
let cell = table.dequeueReusableCellWithIdentifier("electionCell") as! ElectionInfoTableViewCell
cell.electionInfo.text = "hey there"
}
}

How do I append a TableViewCell to a specific Section in Swift

Lets say that I have three arrays in my ViewController. Two of them represent section cells and one represents the sections.
How do I append a TableViewCell to a specific Section?
ViewController.swift:
// represents my 2 sections
var sectionNames = ["Switches","Settings"]
// data for each section
var switchData = ["switch1","switch2", "switch3"]
var settingData = ["setting1", "setting2"]
A better approach would be to use a dictionary instead of separate arrays:
let data: Dictionary<String,[String]> = [
"Switches": ["switch1","switch2","switch3"],
"Settings": ["setting1","setting2"]
]
Here the dictionary keys are the sections and the values arrays are the data for each section.
So, a tableViewController might look like this:
class MyTableViewController: UITableViewController {
let data: Dictionary<String,[String]> = [
"switches": ["switch1","switch2","switch3"],
"settings": ["setting1","setting2"]
]
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return data.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
let sectionString = Array(data.keys)[section]
return data[sectionString]!.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let sectionString = Array(data.keys)[section]
return sectionString
}
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! UITableViewCell
// Configure the cell...
let sectionString = Array(data.keys)[indexPath.section]
cell.textLabel?.text = data[sectionString]![indexPath.row]
return cell
}
}
Result:

Resources