UITableView Cell issue - off screen cells are not shown when scrolled - ios

Only those cell are displaying which are fitting on screen. if scrolled to next(offscreen) cell only white screen is displayed. it allows to scroll but only white space is displayed. Even the last row which was half displayed is also remains half only.
extension LiveTVController: UITableViewDataSource,UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let reuseIdentifier = tableView.tag == 1 ? ProgrammeListCell.reuseIdentifier : StreamListCell.reuseIdentifier
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
if let cell = cell as? StreamListCell {
cell.programmeList.delegate = self
cell.programmeList.dataSource = self
}
return cell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return tableView.tag == 2 ? 10 : 0
}
Now after scrolled down for next rows. there are total 10 sections returned and each section have 1 row.

Specify the height of cell according to cell type.And also place this video view in a table view header instead of using cell for first element.

Related

Increase the height of specific tableview cell dynamically

I've currently multiple items in tableView cell .I want to increase the height of cell when text condition is matched like if name = "john" then increase the height of cell without disturbing another cell. I want to achieve this screenshot result
My current code is
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == tableOrder {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.tableOrderHeight.constant = self.tableOrder.contentSize.height
//self.tableOrderHeight.constant = (6 * 80)
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath ) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PriceTVCell.self)) as? PriceTVCell else {return UITableViewCell()}
return cell
}
first get the index of the row you want to increase the height and use the delegate function heightForRowAt.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == customRow {
return 100.0;//Choose your custom row height
}
}

Custom cell don't appear in tableView

My custom cell don't appear in my table View and I didn't find anything to answer that.
Here's my storyboard that contains the TableView :
This is my listController :
extension MatchListViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MatchCell", for: indexPath) as? MatchTableViewCell else {
return UITableViewCell()
}
let match = matchArray[indexPath.row]
cell.configure(nomDuMatch: match.matchName, scoreFinal: match.finalScore)
return cell
}
}
(I've configured the dataSourceDelegate by storyboard)
the customCell identifier is correct and I really don't understand why nothing appears at launch..
Feel free to ask me more pictures / infos !
Edit :
This is the result :
You need to implement
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100 // or any value
}
or use automatic cell and set constraints properly in IB as it seems that you have a constraints problem and set this in viewDidLoad
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension

How to make footer UITableViewCell not static?

I have 2 prototype dynamic cell called InvoiceDetailCell and TotalCostFooterCell. I make the TotalCostFooterCell as the Footer Cell View using viewForFooterInSection. here is the code I use to assign data to the UITableView
here is my code in UITableViewController.
extension InvoiceDetailVC : UITableViewDataSource {
// MARK: - UI Table View Datasource Methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return invoiceElements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "InvoiceDetailCell", for: indexPath) as! InvoiceDetailCell
cell.invoiceElementData = invoiceElements[indexPath.row]
return cell
}
}
extension InvoiceDetailVC : UITableViewDelegate {
// MARK: - UI Table View Delegate Methods
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "invoiceDetailFooterCell") as! TotalCostFooterCell
cell.totalCost = singleInvoiceData.unpaid
return cell
}
}
but the result is not as I expected, I mean the footer cell is stick / not move. here is the .gif file : http://g.recordit.co/vf0iwCfEWX.gif
you can see the total cost (red colour) is sticky / static, I want that footer cell can be scrolled and always on the bottom. or do I have the wrong to implement what I want?
make the table style to grouped
you can do it in two ways:
In viewDidLoad() do tableView.style = .grouped
Select the table view from storyboard and in the attribute inspector change the style to grouped. Please refer attached image.
Can't you just make it as the last row of the table view? I mean, the view is already a table view cell, so it makes sense to use it as the last row.
First change this:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return invoiceElements.count + 1
}
And then for cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == invoiceElements.count {
let cell = tableView.dequeueReusableCell(withIdentifier: "invoiceDetailFooterCell") as! TotalCostFooterCell
cell.totalCost = singleInvoiceData.unpaid
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "InvoiceDetailCell", for: indexPath) as! InvoiceDetailCell
cell.invoiceElementData = invoiceElements[indexPath.row]
return cell
}
You can set your custom view that you want by:
tableView.tableFooterView = yourCustomView
Or you can put everything inside your xib/storyboard like this:

iOS/Swift: Dynamic UITableViewCell row height with embedded UITableView not working

I have a UITableViewCell which contains a UICollectionView on top and a UITableView on the bottom. The idea is that a dynamic amount of cells will be created in the inner UITableView and the parent UITableViewCell that encloses the two subviews will increase its height proportionally.
I am trying to take advantage of the estimatedRowHeight + UITableViewAutomaticDimentionfeature of the UITableViewCell that will allow the cell height to increase dynamically. However, it is not working. It completely removes the embedded UITableView from view.
I have not made any constraints that limit the height of the enclosed UITableView, so I am not sure why it is not working.
Here is the implementation that attempts to make a dynamically sized UITableViewCell:
class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Enclosed Table View Example"
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 325 // Height for inner table view with 1 cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "appHeaderCell") as! AppHeaderCell
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
return cell
}
}
My only guess is that the constraint bottom = Inner Table View.bottom + 7 is causing the issue, but the entire view falls apart when this constraint is removed.
What can I do to make the complex outer UITableViewCell dynamically adjust height based on the number of cells in the embedded UITableView?
Although it may seem like a good idea, the use of UITableViewAutomaticDimension in conjunction with estimatedRowHeight is not good to use in scenarios like this where we have general content inside table view cells. Making use of the heightForRowAt method, you can calculate the size of each individual cell before it centers the table.
Once we know how many cells will be in the inner table, you need to create an array whose elements correspond to the number inner cells that will ultimately determine the height of the outer cell, as all other content is constant.
let cellListFromData: [CGFloat] = [3, 1, 4]
This array will give us the number of sections in our outer table view:
func numberOfSections(in tableView: UITableView) -> Int {
return cellListFromData.count
}
We will convert each element in this array to a cell height in the following way:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell
let baseHeight = betweenCellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight
let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight
return baseHeight + (dynamicHeight * cellListFromData[indexPath.section])
}
That is, inside of the heightForRowAt method, we dequeue a prototype cell that will not be used in the resulting view (as dequeueReusableCell is not called inside cellForRowAt in this case). We use this prototype cell to extract information about what is constant and what is dynamic about the cell's content. The baseHeight is the accumulated height of all the constant elements of the cell (plus the between-cell spacing) and the dynamicHeight is the height of an inner UITableViewCell. The height of each cell then becomes baseHeight + dynamicHeight * cellListFromData[indexPath.section].
Next, we add a numberOfCells variable to the class for the custom cell and set this in the cellForRowAt method in the main table view:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
cell.numberOfCells = Int(cellListFromData[indexPath.section])
cell.innerTableView.reloadData()
return cell
}
numberOfCells is set with the same cellListFromData that we used to get the height of the cell. Also, it is critical to call reloadData() on the inner table view after setting its number of cells so that we see that update in the UI.
Here is the full code:
class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var outerTableView: UITableView!
let cellSpacing: CGFloat = 25
let data: [CGFloat] = [3, 1, 4]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell
let baseHeight = cellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight
let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight
return baseHeight + (dynamicHeight * data[indexPath.section])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
cell.numberOfCells = Int(data[indexPath.section])
cell.innerTableView.reloadData()
return cell
}
}
class AppCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var innerCollectionView: UICollectionView!
#IBOutlet weak var innerTableView: UITableView!
var numberOfCells: Int = 0
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfCells
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "featureHeaderCell") as! BuildHeaderCell
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "innerCell", for: indexPath) as! InnerCell
return cell
}
}
Methods relating to configuring the inner collection view is not included here as it is not related to the problem.

How do I have two separate cells with two different heights? [duplicate]

This question already has answers here:
UITableview with more than One Custom Cells with Swift
(7 answers)
Swift: How to set dynamic cell height in TableViewController which contains more than one cell
(2 answers)
Closed 5 years ago.
I have two custom cells, but having trouble setting static heights to both those cells, I need the first cell to have a height of 100, but every other cell to have a height of 40. The below code makes all the cells have a height of a 100 instead of just the first one.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if(indexPath.row == 0) {
return 100.0
}
return 40.0
}
You can put your first cell in a different section.
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
}else {
return yourArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! FirstCustomCell
return cell
}else{
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SecondCustomCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 1 {
return 100
} else{
return 40
}

Resources