I have styled the header text:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as? TableViewCell
cell!.titleLabel!.text = sections[indexPath.section].objects[indexPath.row].name
cell!.datetimeLabel!.text = "on " + sections[indexPath.section].objects[indexPath.row].date
return cell!
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 100
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].heading // Open Events
}
And I would like to add some margin / padding below it before the section of the table cells start. I have added some margin / padding top with heightForHeaderInSection. Any way to add some top / bottom margin / padding?
titleForHeaderInSection method will have the default section header frame. You can use viewForHeaderInSection method to customize it. Try this code :
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerFrame = tableView.frame
let title = UILabel()
title.frame = CGRectMake(10, 10, headerFrame.size.width-20, 20) //width equals to parent view with 10 left and right margin
title.font = title.font.fontWithSize(14)
title.text = self.tableView(tableView, titleForHeaderInSection: section) //This will take title of section from 'titleForHeaderInSection' method or you can write directly
title.textColor = UIColor.blueColor()
let headerView:UIView = UIView(frame: CGRectMake(0, 0, headerFrame.size.width, headerFrame.size.height))
headerView.addSubview(title)
return headerView
}
Hope this will work for you.
use viewForHeaderInSection: and return a view with a label with the correct spacing below it instead of using the default header in titleForHeaderInSection
see this answer for an example
Related
I'm a beginner trying to learn Swift
I'm trying to make my own section header by creating a uiview and adding a label to it before returning it. However the label is never displayed, only the uiview.
I cannot see what I'm doing wrong?
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sectionHeaderView = UIView()
sectionHeaderView.backgroundColor = UIColor.lightGray
sectionHeaderView.layer.cornerRadius = 0
let sectionLabel = UILabel()
sectionLabel.text = "Test"
sectionLabel.textColor = UIColor.black
sectionLabel.font = UIFont.boldSystemFont(ofSize: 16)
sectionHeaderView.addSubview(sectionLabel)
return sectionHeaderView
}
I forgot to add sectionLabel.sizeToFit()
Thanks maddy!
I have a UITableView, it uses a custom UIView as the section header view. Code like so:
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ECStartTableHeaderView") as! ECStartTableHeaderView
return headerView
}
I have UITableViewAutomaticDimension for the height on the header. I need to find out what this height is in my code. How can I get this header height?
I think you have to ensure your header layout finished first, so you can get actual height.
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let height = view.frame.height
}
You can take out the Height of the Header View Just Like.
if let headerView = tableView.tableHeaderView {
height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
}
I'm implementing a tableview, which has 3 sections(section count remain static) and each section contain several rows.
Behaviour 1: Add section header to only the third section.
How did I achieve:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 2 {
//create and return header view
}
return UIView(frame: CGRect(x: 0, y:0, width: tableView.width, height: UIScreen.main.scale))
}
Behaviour 2: TableViewCells shouldn't have separator. But, Sections should be separated with a thin line. (similar to tableviewcell separator)
What did I try:
Add a one pixel height, tableView width UIView, with all required properties set(color, etc) and add it as a sub-view to the section header view's
Add drop shadow with CGPoint(0,1) to the section header views
None of them worked out.
How did I achieve this:
Find last cell in every section,
Create an UIView with 1px height, tableView's width and add it as a subview to the last cell
Though this seem to work. I feel, there must be a better way of doing this, rather than adding line to bottom of every section's last tableView cell. Does anyone know a better way of implementing such behaviour?
Set the Style of the Table View to Grouped:
Using heightForHeaderInSection method of UITableViewDelegate and return section wise height as per you want
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 2 {
return 1 // return height as per your requirement
}
return 0 // return height as per your requirement
}
This should work for adding "section separator lines" and a head view only on the 3rd section:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// if it's the 3rd section, return a view with desired content for the section header
if section == 2 {
let v = UIView(frame: CGRect(x: 0, y:0, width: tableView.frame.width, height: 30))
v.backgroundColor = .yellow
let label = UILabel(frame: CGRect(x: 8.0, y: 4.0, width: v.bounds.size.width - 16.0, height: v.bounds.size.height - 8.0))
label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
label.text = "Header for Third Section"
v.addSubview(label)
return v
}
// not the 3rd section, so don't return a view
return nil
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// if it's the 3rd section
if section == 2 {
return 30
}
return 0
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
// UIView with darkGray background for section-separators as Section Footer
let v = UIView(frame: CGRect(x: 0, y:0, width: tableView.frame.width, height: 1))
v.backgroundColor = .darkGray
return v
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
// Section Footer height
return 1.0
}
Simple solution of this Just add the footer view inside the tableview.Set height of the footer view to be a specific height.
Swift:
public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = UIColor.grey
return view
}
public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 10
}
I am currently working on a UITableViewController. My current implementation includes a header view (white view), a UITableView section header (red view) and tableview (grey). Currently the TableView style is grouped so the Section Header scrolls with the TableView when scrolling up to shrink the header view.
I am trying to keep the Section Header at the top of the view when the header view goes offscreen, and allow the UITableViewCells to scroll under the Section Header. Currently the tableview cannot scroll up once the Section Header reaches the top of the view. Any suggestions would be super helpful
Current Code:
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 106.0
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view1 = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 106.0))
view1.backgroundColor = UIColor.red
return view1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80.0
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let maxOffset = (scrollView.contentSize.height - scrollView.frame.size.height)
if scrollView.contentOffset.y >= maxOffset {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: maxOffset)
}
if scrollView.contentOffset.y >= 35.0 {
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: 35.0)
}
}
}
I am not completely sure I follow what you are trying to accomplish, but please allow me to attempt to infer and feel free to provide clarifications. I like the table view practice :)
As I understand it:
1) You want the white view, the red view, and the table cells beneath the red view to scroll upward from the default position
2) You want the white view to scroll out of visibility
3) You want the red view to float at the top while the cells scroll beneath it
4) You currently have the white view as a table header, the red view as a section header, and the gray area are table cells
Sounds like a cool app!
Why not use 2 table sections:
1) Drop the table header
2) Set the white view in cell 0 section 0 of the table view.
3) Set table delegate methods so section 0 will have a nil header with 0 height
3.5) Also set the table delegate methods so section 1 will be your main table
4) Use UITableViewStylePlain so section 1 header will float at the top
Is this the desired functionality?
I was able to replicate your desired behaviour without using the scrollViewDidScroll method, however the headerView will no longer scroll with the tableView. You could use the scrollViewDidScroll method to change the height/origin of the headerView when the content offset is less than zero.
class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var headerView: UIView?
#IBOutlet weak var tableView: UITableView? {
didSet {
tableView?.dataSource = self
tableView?.delegate = self
}
}
func numberOfSections(in tableView: UITableView) -> Int { return 1 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.backgroundColor = UIColor.gray;
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 50))
header.backgroundColor = UIColor.red
return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 100 }
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 60 }
}
I have a UITableViewController and I am setting the footerView via
self.tableView.tableFooterView = FooterView()
In the class FooterView I have added a label via
self.addSubView(label)
I noticed the following.
The footerView is positioning on top of the tableView
The label is inside the footerview
My questions are
When I set the Frame of the footerView as (0, 0, 100, 100) it seems to be overlapping on the tableView. How do I position the footer at the bottom of the tableView ?
When a label is added via addSubView() of the footer. Is it positioning related to the footerView or the tableView?
FooterView's default height is 44.If you don't set your footerView's height for more and then set your label with height of 100 then it overlaps.
It is positioning with the footerView.
You can set the footerView's height by using UITableViewDelegate method.Below is the way to achieve what you wanted.Footer view only at the bottom of table view.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView .dequeueReusableCellWithIdentifier("cellIdentifier") as! UITableViewCell
cell.textLabel?.text = "trial"
return cell
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if section == 1{
return 100
}
return 0
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2 //The number you needed + 1
}
func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == 1{
return FooterView()
}
return nil
}
Delete this line
self.tableView.tableFooterView = FooterView()