There are two questions to this post. I've a project that fetches JSON data, and stores in NSArray. The data will be extracted and display on UITableView.
This is the screenshot of my data during debug, and I've verified that I've successfully fetch the data.
I've 2 questions to this post.
Why when I do var count = resultJSON.count, the value is 0?
Because of the 1st part, I've failed to display the data of resultJSON on my table. So in order to "cheat" I return 9 to see if the data does display. However I can't display out to my table.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
//let count = resultJSON.count
return 9
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let myCell = stockTableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! UITableViewCell
for jsonObjectString in self.resultJSON{
myCell.textLabel?.text = jsonObjectString["name"] as! String
myCell.detailTextLabel?.text = jsonObjectString["company"]! as! String
}
return myCell
}`
Related
How to implement two xib cells and only one array, if array count is nil show empty xib cell and if array count is not nil show xib cell with data swift. Please solve the problem i have searched lot of no answer is related to me.
This example assumes your data array is named myData:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return either 1, or the count of your data, whichever is greater
return max(1, myData.count)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// if it's the first row, and your data is empty
if indexPath.row == 0 && myData.count == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "emptyCell", for: indexPath) as! EmptyCell
return cell;
}
let cell = tableView.dequeueReusableCell(withIdentifier: "dataCell", for: indexPath) as! DataCell
// populate the cell
return cell
}
I have a table view that keeps track of hotel receipts (each time the user enters the date, cost, and name of the hotel and hits the add button it adds a new row to the table with the information.
I have 2 text fields below the table that I want to show the total entries (number of rows) and the sum of the cost field. Problem is I can't figure out how to do this or if it is even possible.
I have found a couple posts about it but they all seem to have a set number of rows.
extension HotelViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
let numberOfSections = frc.sections?.count
return numberOfSections!
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let numberOfRows = frc.sections?[section].numberOfObjects
return numberOfRows!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HotelCell", for: indexPath) as! HotelTableViewCell
let item = frc.object(at: indexPath) as! DriveAwayHotel
cell.date.text = item.date
cell.name.text = item.name
cell.cost.text = "$\(item.cost ?? 0.00)"
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
let managedObject : NSManagedObject = frc.object(at: indexPath) as! NSManagedObject
pc.delete(managedObject)
do {
try pc.save()
} catch {
print(error)
return
}
}
You should not try to do math on your cells. You should do math on your model.
Are you trying to sum all the entries in your table, or just the cells that are visible?
If you want to sum all the entries in your table view, then loop through all the sections in your frc.sections array, loop through all the entries in each section, and add them all up. (That code would be easy to write.)
If you only want to sum the entries for the currently visible cells, call the table view's indexPathsForVisibleRows method to get an array of the indexPaths of the cells that are visible, loop through those indexPaths, fetch the entry at each section and row, and add those together. (That code would also be easy to write.)
EDIT:
The code to sum all your entries might look something like the below (I'm having to guess a bit since I don't know your data model)
var total = 0.0
guard let sections = frc.sections?.count else { return }
for section in 0..<sections {
guard let rows = frc.sections?[section].numberOfObjects else { continue }
for row in 0..<rows {
let indexPath = IndexPath(row: row, section: section)
let item = frc.object(at: indexPath) as! DriveAwayHotel
total += item.cost
}
}
I want to load Identifier according to odd and even indexPath.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
if indexPath.row % 2 == 0{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! categoryTVC
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("CellOdd", forIndexPath: indexPath) as! categoryTVC
return cell
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.categoryDetailArray?.count ?? 00
}
this work but there is one problem with this ..its generate one extra cell each time.
Your code is correct. But you should remember that if you want equal number of odd and even cells then you should have even number of cells.
So you have to supply either 24 or 26 (an even number of rows) not 25(odd number of rows) in numberOfRowsInSection method.
My Situation: I want to save Data from an Array at Index X in an Row on Index X in Section 1.
My code is:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return setObjectToPass.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section \(section)"
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellEmpty = tableView.dequeueReusableCellWithIdentifier("LabelCell")
var countCell = 0
while countCell < setObjectToPass.count {
let indexPaths = NSIndexPath(forRow: countCell, inSection: 0)
let cell = tableView.dequeueReusableCellWithIdentifier( "LabelCell", forIndexPath: indexPaths)
cell.textLabel!.text = String(setObjectToPass[countCell])
print(cell)
countCell+=1
return cell
}
My Problem is that only the first index of the Array SetObjectToPass is passed and set into the Cell.text
while counter < fetchResult?.count {
let set = fetchResult![counter]
counter+=1;
setObject.append((set.reps?.integerValue)!)
}
You are implementing the tableView(_:cellForRowAtIndexPath:indexPath:) method wrongly.
Remember, every delegate method in UITableViewDelegate is like asking you a question. For example, numberOfSectionsInTableView(_:) is like asking you "How many sections do you want in your table view?". You answer the question by returning a value.
tableView(_:cellForRowAtIndexPath:indexPath:) is similar. It asks a question as well. It asks "What should I display in the table row at this index path?"
In your code, it seems like you want to give multiple answers - looping through the array and attempting to return multiple times. But it doesn't work that way, you can only give one answer.
In the first iteration of the while loop, the execution hits return and stopped. That's why you only see the first table cell.
Thus, you should change your code so that it only gives one answer to the question:
let cell = tableView.dequeueReusableCellWithIdentifier("LabalCell")
cell.textLabel?.text = String(setObjectsToPass[indexPath.row])
return cell
Don't use the loop in cellForRowAtIndexPath delegate method. cellForRowAtIndexPath method call each row based upon numberOfRowsInSection count rows, simply use indexpath.row, Use this code,
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellEmpty = tableView.dequeueReusableCellWithIdentifier("LabelCell")
let cell = tableView.dequeueReusableCellWithIdentifier( "LabelCell", forIndexPath: indexPaths)
cell.textLabel!.text = setObjectToPass[indexPath.row] as? String
return cell
}
hope its helpful
I'm making an social networking app with a NodeJS backend. The app gets its data from the MongoDB associated with the Node app with a GET request. I have figured out how to parse the JSON returned from the GET request as a native Dictionary, but can not find a clean way of turning each of the objects in the dictionary into a TableViewCell in my TableView. The Dictionary is basically this:
["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
I need each of those to fill different values/labels inside the TableViewCells
If you want to utilize indexPath, I would keep a copy of array of dictionary keys.
func fetchData() {
// ....
// Your own method to get the dictionary from json
let self.userDict = ["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
// Keep a copy of dictionary key
let self.userDictKeyCopy = Array(self.userDict.keys)
// You may want to sort it
self.userDictKeyCopy.sort({$0 < $1})
}
// Table view delegates
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.userDictKeyCopy.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(kCustomCell) as! CustomTableCell
// Assuming one section only
let title = self.userDictKeyCopy[indexPath.row] // e.g. "taggedUsername"
cell.titleLabel = title
cell.contentLabel = self.userDict[title] // e.g. "personWhoIsTagged"
return cell
}
let yourDict = ["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
Number of rows in section
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourDict.count
}
Cell for row at
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let key = Array(yourDict)[indexPath.row].key
let value = yourDict[key]
return cell
}