I have a problem that I couldn't find any appropriate solution.
I have a tableView with custom cells which holds a textView inside.
also I have a blank grey footer for the section.
whenever I click on the textView and the keyboard pops up the footer in that section goes up and hides behind the textView field.
I don't know how to make that footer sticky so it won't move when the keyboard pops.
if anyone have a solution it will be great!
thank you!
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == 0 {
let footerView = UIView()
footerView.backgroundColor = .red
return footerView
}else {
return UIView()
}
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 8
}
Set your tableView as grouped give height to the tableview footer and tableView Header in the tableview header,footer height functions.
If you are not using tableview header the set the height of the header to .leastNormalMagnitude .
This is the way to make the tableView Footer Static.
Related
I have a UITableView with multiple sections with the header, collapsable/expandable. And also a tableHeaderView with custom UIView.
Using custom section header UIView and also custom UITableViewCell.
When all sections and rows are fully expanded, there is this weird scroll behavior, when I'm scrolling to the top (scroll down), when I reach the very top, the large navigation bar title should follow my scroll down gesture and animate down its way (Bounce effect). However, in this case, the bounce effect did not happen, the moment I scrolled to the top and try to scroll more for bounce effect, the scroll automatically got cut off and the navigation bar automatically becomes a small title.
Surprisingly, when I collapsed all the rows of the first section, the scroll behavior goes back to normal.
Here's a gif to show my screen recording.
https://i.imgur.com/WwXmpmZ.gifv
I have set the following to my UITableView:
self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 15, right: 0)
self.tableView.estimatedRowHeight = 0
self.tableView.estimatedSectionHeaderHeight = 0
self.tableView.estimatedSectionFooterHeight = 0
I have also tried:
self.tableView.contentInsetAdjustmentBehavior = .never
This indeed solved the weird scrolling behavior, however it causes my section headers and rows to overlap with my tableHeaderView.
The way I handle the collapse/expand. If the object property isCollapsed is true, I just simply return 0 row for that section:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == self.scheduleCount {
//Last section
return self.dataSource.count
}
guard let schedule = self.itineraryDataSource?.schedule[section] else { return 0 }
if schedule.isCollapsed {
return 0
} else {
return schedule.items.count
}
}
These are all the height delegates, the last section is having different UITableViewCell, hence the different height.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == self.scheduleCount {
//Last section
return 40
}
return 64
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == self.scheduleCount {
//Last section
return 112
} else {
return 76
}
}
Managed to fix this.
Turns out I was returning UIView for my viewForHeaderInSection and I wasn't using tableView.dequeueReusableHeaderFooterView. I literally init a new xib UIView every time I scroll the tableView which causes it to automatically adjust the content inset, hence, caused the jerky scroll.
So, I created new custom xib for my section header view with type UITableViewHeaderFooterView, and simply return it at viewForHeaderInSection.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let dayHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ItineraryDayHeaderView") as? ItineraryDayHeaderView
// Configure View...
return dayHeaderView
}
We're want to do two changes to our search results.
Change the Collection View Controller to a Table View Controller
Have only the second section header show and have it scroll away inline. In other words, don't be sticky and don't stay at the top.
In regards to changing the Collection View Controller to a Table View Controller. This involves changing the section headers from a UICollectionReusableView subclass to something else. Normally, the change would be to using a UITableViewHeaderFooterView.
In regards to making the second section header scroll on up inline and out of sight and thus not be sticky, there's an issue to my solution.
To make it non-sticky, I changed the tableview to be UITableViewStyleGrouped. This causes a look for the second section that is different than what we have now. We would like it back to how it looks now.
Here's what we have in the App Store now:
Here's what we have when trying the UITableViewStyleGrouped approach and other changes:
Notice the extra gray above the "Other cars..." section header? I figure I can probably solve the rounded corners and insets via a subclass of the UITableViewHeaderFooterView. However, it's not clear how to handle the extra space above the section.
Code:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 800
self.tableView.rowHeight = UITableViewAutomaticDimension
let nib = UINib(nibName: "SearchResultsOtherCarsHeader", bundle: nil)
tableView.register(nib, forHeaderFooterViewReuseIdentifier: "SearchResultsOtherCarsHeader")
:
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section != 1 {
return 0
}
return 30
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section != 1 {
return nil
}
let searchResultsOtherCarsHeaderView = self.tableView.dequeueReusableHeaderFooterView(withIdentifier: "SearchResultsOtherCarsHeader") as! SearchResultsOtherCars
return searchResultsOtherCarsHeaderView
}
How to get rid of the extra gray space above the section header?
The solution:
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.01
}
This solution was inspired by the comment made by #maddy and iPhone UITableView : How to remove the spacing between sections in group style table?
I have a table with white empty area at the bottom of table view. But I want this area to be gray. I have added a gray footer but it is too much small.
What shall I do?
Set tableView's backgroundColor as gray color and tableFooterView with empty UIView
self.tableView.tableFooterView = UIView()
self.tableView.backgroundColor = .gray
Add the below lines,
self.tableView.tableFooterView = UIView()
It will works perfectly.
if its because of tableview footer then use the below delegate methods else if its the background view colour modify you tableview to fit the parent view rect
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView()
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0
}
Im trying to implement a tableview that has cells with a product image on the left side and a listing of various product details such as price, title, etc. to the right of the image, however, I have been having trouble with setting up the appropriate spacing/padding between the cells. I want each cell to have some white space between them. Here is an image showing what i have so far, and what the issue is.
TableView
I am using a stackview as a container for the labels with the product details, and am implementing the dynamic row height feature:
self.tableView.rowHeight = UITableViewAutomaticDimension
Everything seems to work great except wajjhen the stackview height is smaller than the imageview height. I can't get the spacing to show in that scenario. I have tried everything for the past 2 days, and it is driving me crazy. Take it easy on me guys as I am an Android guy :)
All I want is for the I want the separators of tableview cells to have a bit of space between either the top and bottom of the imageview or the stackview(whichever is taller/higher).
I have attached a SS of the storyboard to show the layouts and constraints. Please let me know if any more information is need.
Storyboard
for adding consitent spacing to your cell better way is to treat your each item as a section because you can set spacing easily between sections by creating a header view between section.
So logically if you have 10 objects than you will be having 10 section with each section have only one row.
1.Each section with only one row
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
2.Number of section is equal to count array of items
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return array.count
}
3.Set Hieght for spacing/header view
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
4.create your header view and customise it
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let view = view as? UITableViewHeaderFooterView{
view.backgroundView?.backgroundColor = UIColor.clearColor()
}
}
Assuming that you have no problem with setting the appropriate height for each cell (if you have, you might want to check this Q&A), I suggest to let each cell on a section instead adding them in the same one.
Technique:
By default, if you are not implementing numberOfSections(in:), it returns 1. You should:
implement it and let it returns the number of array data source -for example- (instead of doing it in tableView(_:numberOfRowsInSection:)).
Let tableView(_:numberOfRowsInSection:) returns 1. Each section will has only one cell.
After that, the trick is to add a header view for the sections (with a clear background color) with desired height, the height will be the margin between the section (cells in your case). You should achieve this by implementing:
tableView(:viewForHeaderInSection:) and tableView(:heightForHeaderInSection:).
The code will be similar to:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// ...
// MARK:- UITableViewDataSource
func numberOfSections(in tableView: UITableView) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell-ID")
// note that you should read from 'indexPath.section' instead of 'indexPath.row'
let currentObejct = dataSource[indexPath.section]
}
// MARK:- UITableViewDelegate
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// here, you can customize the header
// or your case want to let it clear...
let margin = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 20.0))
margin.backgroundColor = UIColor.clear
return margin
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 20.0
}
// ...
}
Hope this helped.
You can try giving the Fruit Image a top and a bottom constraint but they must be >= so it doesn't mess your auto layout
And your constraints will probably look like this
3 days later, I finally found a solution I am content with, albeit it is quite janky, but at this point(3 days of dealing with this issue), I don;t really care. I am posting my solutuion in case it helps anyone in the future.
I ended up pinning a view to the tableviewcell with a minimum height of 130 to contain the imageview and stackview. Since I know the minimum height of the tableviewcells is 120, 130 gave a padding of 5 on the top and bottom. I attached the screenshot of my storyboard:
Storyboard
TableView
I want to make a custom footer for my UITableView.
For that, I will need the position of the last cell in the UITableView and set my UIView under the TableView.
But I don't know how to get the position of the last cell.
Is it even possible to make this kind of custom Tableview-footer?
You can add a footer directly in the storyboard or xib--just drag your view so that it's inside your tableView, but after all of the tableView's cells.
You don't need to make custom footer or to know the position of your last cell. It is already available on UITableViewDelegate.
You need to make a custom UIView then on the callback of func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? return the UIView.
Example:
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let view = UIView.init(frame: CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height))
view.backgroundColor = UIColor.greenColor()
return view
}
The above code will give you a green UIView for the UITableView. Just make sure you do not set the Footer height to 0 on Storyboard or on code.