Remove extra cells/rows whitespace without data appearing on UITableView - ios

I m populating UITableView with data and works fine too.
But my issue is , when the UITableView has less number of rows of data it shows rows with data properly but shows a whitespace .
For example: if the tableview has 1 row to display it shows that row then under that there are whitespaces like empty rows.
I tried
tableView.tableFooterView = UIView()
and
tableView.tableFooterView = UIView(frame: CGRectZero)
Screenshot:
But both just removed the Cell borders not the extra whitespace appearing.
Please suggest. Thanks in advance.
Edit :
Select Button is not Part of the Cell. Just trying to Click on Select Button and then the UITableView Displays under it. ( Like a DropDown ).
Also , using default Tableview Cell not a Custom TableView Cell
Code :
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cityList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cityCellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
cell.textLabel?.text = self.cityList[row].cityEn
print("CityName" + self.cityList[row].cityEn )
return cell
}
StoryBoard ScreenShot

If you don't want the empty cells set the TableView style from Plain to Grouped.

Adding to #choli answer You can do 2 things,
adjust the height of the table view based on the rows,
Resize UITableView's height to be as high as it needs to fit only total content size
Simpler solution would be to clear table background color
tableView.tableFooterView = UIView(frame: CGRectZero)
tableView.backgroundColor = UIColor.clearColor()

Sorry, I would comment, but not enough reputation:
This is the tableView size, whenever the full tableview is not filled with rows, it shows some extra rows that are empty. If you don't want this, then you have different possibilities:
you could make the size of the tableView smaller - e.g. the number of cells * cellHeight
you can change the appearance of the tableView, so it will be clearColor instead of white, so the placeholder cells will be invisible.

Related

Resizeable tableView cell with tableView inside it

I am creating a tableView with custom cells in which each cell can have different types of views ranging from key-value pair labels, map, buttons , list and more depending upon the data coming from the server and those views will be populated accordingly. I have created custom XIB for each view type which i will be using
So for this I took a parentTableView whose cell will have a childTableView whose each cell will be the different type of view depending on the data from the server
NOTE - Call and Navigation button and Assigned label are not cells but are added on top of the cell
Now I have two questions :
How can i make the childTableView to disable scrolling feature and take the full height of its content (In the image after last assignedTo, there is a priority field which is currently clipped as i have defined the height of the tableView cell to be 200 )
Dynamic height for parentTableView's cell (which is almost similar to first question)
I tried setting rowHeight and estimatedRowHeight for parentTableView but it is collapsing the cells
parentTableView.rowHeight = UITableViewAutomaticDimension
parentTableView.estimatedRowHeight = 300.0
remove parentTableView.rowHeight = UITableViewAutomaticDimension
and update your cell height to calculated cell.tableView.contentSize.height
ref:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = tableView.dequeueReusableCellWithIdentifier("identifier", forIndexPath: indexPath) as! CustomCell
return cell.tableView.contentSize.height
}

How to prevent tableview section head from sticking while scrolling?

I have a tableview with many sections. I am using an actual tableview cell which I dequeue to use as a custom section header. The issue I am having is when I scroll the section header "sticks" to the top of the table until the next section appears.
How can I prevent this from happening and actually have it scroll up like normal?
Here is my code
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 3 {
let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderTableViewCell
return cell
}
return UIView()
}
Do following steps.
From #IB
Select your tableView
Go to Attribute Inspector
Find Style Attribute drop down which is Plain by default
Change it to Grouped
Or if you are creating TableView Programmatically use
let tableView = UITableView(frame: YourFrame, style: .Grouped)
Change UITableViewStyle to UITableViewStyleGrouped.
Set UITableViewStyle to UITableViewStyleGrouped, the headers will scroll up with the cells.
and
func tableView(_ tableView: UITableView,
heightForFooterInSection section: Int) -> CGFloat
{
return 0.000001;
}
Step1: Go to Mainstoryboard
Step2: Click on Your Tableview
Step3: Go to Attribute Inspector
Step4: Find Style Attribute drop down which is Plain by default
Step5: Change it to Grouped
Some possible solutions :
If you have just one section then set the Tableview Header property to the UIView you want to set as the Section Header.
If you have multiple sections, change the row count for each section to (number of rows for that section + 1) and make the row at 0th index to be a header. Some hand coding will be required.
Change your tableview to grouped, will require UI redesign so that the design looks similar to a plain tableview cell.
Instead of UIHeaderViewCell, You should use a UITableViewCell. Make section header height as 0 and for every 0th item in that section , display a UITableViewCell with heading on it

How to create tableview cells without using prototype cells?

In my tableview, every cell will be different and determined by a JSON response from server. And there will be infinite possibilities. So defining a prototype for each type of cell is not possible.
For example, one cell will have labels and buttons, another cell have images and buttons in different orders.
How to achieve this dynamic structure in tableview cells?
Currently what I am doing is: adding views as subview in cellForRowAtIndexPath but scrolling is very laggy this way.
How to achieve this without affecting performance this much
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! MyCell
for myview in data[indexPath.row].myviews{
cell.addSubview(myview)
}
return cell
}
If you're using a table view then your content is going to scroll vertically, right?
There is a physical limit to the amount of UI that you can put horizontally. Limited by the screen size.
So I'm guessing your UI parts are being laid out vertically in the cell?
So instead of laying out a button, label, image, another button, and a text field vertically in a cell...
Create a cell type called ButtonCell, LabelCell, ImageCell, MultiLineLabelCell, TextFieldCell, etc...
So now, instead of creating one cell with all these elements added. You instead create multiple cells each containing one type of UI. Now you can dequeue your cells in any particular order (driven by your JSON) and won't lose the performance.
The only solution I see is to have empty cell and add/remove subviews as needed. But you should add new subviews to a cell only if you did not add them before.
For example:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! MyCell
if cell.contentView.viewWithTag(1) == nil {
let label = UILabel()
label.tag = 1
cell.contentView.addSubview(label)
}
let label = cell.contentView.viewWithTag(1)
// label config there
return cell
}
Also don't forget to add subviews to cell's contentView not to cell itself.

UITableview Height set according to cells

I have UITableView in UIViewController in this view controller total 3 tableview or 2 UICollectionView. so in this one tableview contain many cells or cells data are not static its dynamic according to server. So, I create the table view height outlet & its set on cellforrowatindex function of tableview.
So, we use to set height tableview_height.constant=tableview_height.constant+cell.frame.size.height using this code my problem showing whitespace on the end of UITableViewCell. If I increase the cell then cell are cut from the bottom. I am giving below constraint show in the pic.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.row == 0
{
tableview_height.constant = 0
tableview_height.constant=tableview_height.constant+cell.frame.size.height
}
else
{
tableview_height.constant=tableview_height.constant+cell.frame.size.height
}
return cell
}
Check my answer on the almost same question.
How to increase the height of parent view according to height of UITableView in swift?
It is the best way to achieve what you want, because it does not depend on your table settings or if you have header/footer/custom insets/whatever.
Hope it will help.

TableView separator disappear

When I select rows from top to bottom, separator appears. However when I scroll the rows, the separator removed.
When I select rows from bottom to top, separator doesn't appear.
How can I keep the separator always existed?
I have searched for a while and seems there is no solution yet.
When you simply add a UITableView, it shows the separator like these. The separator remains there when you select, reload or perform any other function.
Other can be check if the separator is selected to default or none.
At one time you can select single row only. The selection color being same as the separator. It appears there is no separator. Plus when you have multi select. Its default functionality that it appears that there is no separator.
// create a cell for each table view row
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier) as UITableViewCell!
// set the text from the data model
cell.textLabel?.text = mainArr[indexPath.row]
//Main item here is set selection style none.
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
and when you select a row, add a new UIView or ImageView to the cell which is same width as cell view but height should be cell.height-1
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
let cell = self.tableView.cellForRowAtIndexPath(indexPath)
var customView = UIView(frame: CGRectMake(0, 0, (cell?.frame.width)!, 43))
customView.backgroundColor = .redColor()
customView.alpha=0.3
cell!.addSubview(customView)
}
In this manage an algorithm, that way you can come to know if the row has to be selected or deselected and that way add the view or remove the view from the cell.

Resources