enter image description here
I have a tableView with X number of cells, every cell has 1 table view with N number of cells.
How to make every x cell fits the the content size of it's sub tableView.
I think you should use table view with sections, so your X number of cells will be the number of sections in this case, and N number of cell will be number of rows in that section.
//MARK: TableView Delegate
func numberOfSections(in tableView: UITableView) -> Int {
return X
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourIdentifier") as? YourTableViewCell
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfRows
}
Hope that is what you need.
Related
Hello,
i have created a UITableView in which it has two different cells DynamicFormCell and StaticFormCell, so the DynamicFormCell can be displayed number of times i have a data from a server telling me how many forms i need for the DynamicFormCell and the StaticFormCell is always the same and doesn't change so i am having difficulty giving different number of rows for each cell.i tried giving the two cell a tag of 0 and 1 respectively and used this code:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(tableView.tag == 0){
return 5//return five dynamic cells
}
if(tableView.tag == 1){
return 1//return one static cell
}
}
but this doesn't work and i also tried removing all the tags and if statements in the above code and just doing this return 5 this just gave me one DynamicFormCell and five StaticFormCells.
i also gave different classes for the two cells so i can assign them separately:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row == 0){
//firstRow make dynamic
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicFormsCell") as! DynamicFormsCell
return cell
}else{
//static form data
let cell = tableView.dequeueReusableCell(withIdentifier: "StaticFormsCell") as! StaticFormsCell
return cell
}
}
so my question is, is it possible to do this using table views and how can i do it? if not what other options do i have?
Yes it is possible to have multiple types of cell in single tableview. It has nothing to do with function
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
You should return there cells as,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (count of dynamic cells + count of static cells)
}
I assume, you only have to display static cells in the bottom. So if there are total 5 cells then 4 cells are dynamic and 5th cell would be static.
So code for, cellForRowAt indexPath: will be,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row < (count for dynamic cells)){
//first 4 Rows make dynamic
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicFormsCell") as! DynamicFormsCell
return cell
}else{
//last row static form data
let cell = tableView.dequeueReusableCell(withIdentifier: "StaticFormsCell") as! StaticFormsCell
return cell
}
}
What you're doing right now is checking if the TableView's tag is 0 or 1. Which is not you want to do, since you're using only one TableView.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (amount of DynamicCellsYouWant + amount of StaticCellsYouWant)
}
The second part of your code only works when you want the first cell to be a DynamicFormsCell and the rest to be a StaticFormsCell.
I am currently making a golf round tracker that displays your rounds in a table view with the cells being xibs. When I add one round, it appears fine on the table view, but when I add another round it adds that cell and doubles the cells. Here is a picture of what happens: https://i.stack.imgur.com/SOgN4.png. Here is my code:
class RoundDisplay: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
arrayOfCellData.append(roundData(id : arrayOfCellData.count + 1, date : datePlayedFC, course : currentCourse, score : String(score1234) ))
tableView.reloadData()
print(arrayOfCellData)
}
override func numberOfSections(in tableView: UITableView) -> Int {
//Shows how many cells it should display; number of current cells
return arrayOfCellData.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//Shows how many cells it should display; number of current cells
return arrayOfCellData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//Defines what xib to use for cells
let cell = Bundle.main.loadNibNamed("TableViewCell", owner: self, options: nil)?.first as! TableViewCell
//Adds array data to each cell
cell.DateLbl.text = arrayOfCellData[indexPath.row].date
cell.CourseName.text = arrayOfCellData[indexPath.row].course
cell.ScoreLbl.text = arrayOfCellData[indexPath.row].score
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//Shows how high to make cells; height of xib
return 68
}
}
The number of sections function needs to be set to one. I realized that it decided how many cells it should show for the data from the array. Which means if you have the function set as I did, for instance, if you had two sets of data in the array, it would put two cells for each data. Thanks to #Magnas and #vacawama for the help!
So every time I scroll my tableView it reloads data which I find ridiculous since it makes no sense to reload data as it hasn't been changed.
So I setup my tableView as follows:
func numberOfSections(in tableView: UITableView) -> Int {
return self.numberOfElements
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 6
}
My cells are really custom and they require spacing between them. I couldn't add an extra View to my cell to fake that spacing because I have corner radius and it just ruins it. So I had to make each row = a section and set the spacing as a section height.
My cell has a dynamic height and can change it's height when I click "more" button, so the cell extends a little.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if self.segmentedControl.selectedSegmentIndex == 0 {
if self.isCellSelectedAt[indexPath.section] {
return self.fullCellHeight
} else {
return self.shortCellHeight
}
} else {
return 148
}
}
And here's how I setup my cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if self.segmentedControl.selectedSegmentIndex == 0 {
cell = tableView.dequeueReusableCell(withIdentifier: String.className(CurrentDocCell.self)) as! CurrentDocCell
(cell as! CurrentDocCell).delegate = self
(cell as! CurrentDocCell).ID = indexPath.section
} else {
cell = tableView.dequeueReusableCell(withIdentifier: String.className(PromissoryDocCell.self)) as! PromissoryDocCell
}
return cell
}
So I have a segmentedControl by switching which I can present either one cell of a certain height or the other one which is expandable.
In my viewDidLoad I have only these settings for tableView:
self.tableView.registerCellNib(CurrentDocCell.self)
self.tableView.registerCellNib(PromissoryDocCell.self)
And to expand the cell I have this delegate method:
func showDetails(at ID: Int) {
self.tableView.beginUpdates()
self.isCellSelectedAt[ID] = !self.isCellSelectedAt[ID]
self.tableView.endUpdates()
}
I set a breakpoint at cellForRowAt tableView method and it indeed gets called every time I scroll my tableView.
Any ideas? I feel like doing another approach to make cell spacing might fix this issue.
A UITableView only loads that part of its datasource which gets currently displayed. This dramatically increases the performance of the tableview, especially if the datasource contains thousands of records.
So it is the normal behaviour to reload the needed parts of the datasource when you scroll.
I'm trying to achieve something like the image at the bottom of the page . Specifically:
Add spacing between each cells (in a different group you could say.)
Add text above or below the cell.
Have empty space everywhere else with no cells.
I want everything to look exactly like this image.
(Ignore the text, navigation bar, and anything inside the cells.)
I have already tried this and came out with this image below:
This is my code from what I have tried:
let data = [["0,0", "0,1", "0,2"], ["1,0", "1,1", "1,2"]]
let headerTitles = ["Some Data 1", "KickAss"]
// MARK: - TableView Data Source Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let cellText = data[indexPath.section][indexPath.row]
cell.textLabel?.text = cellText
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section < headerTitles.count {
return headerTitles[section]
}
return nil
}
TableView State This document will help you for tableview state. (loading, data, empty states)
I try to display a simple cell with one label and an add item button. I can't get it to display correctly. I spent a lot of time but I can't find the solution.
This is the result:
There is no add item button and no correct row. I have just two items in coredata.
This is my code:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return items.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
let data = items[indexPath.row] as Item
cell.textLabel?.text = data.body
return cell
}
What are the problems? Can anyone help me to display add item button, correct row count, and customize height of the cell correctly? Thanks in advanced.
First lets return the correct number of rows unto the table view.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellContent.count
}
Next lets get it to output unto the prototype cells.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = cellContent[indexPath.row]
return cell
}
Also lets call the unto the view controller the following so that it can run properly.
ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
One last thing, your prototype's cell has the same identifier as the one in your code. In my code I would make sure that the identifier in the prototype cell is "Cell" since I called it in UITableViewCell(...reuseIdentifier: "Cell").
View picture to see where to add the identifier in your storyboard