Re-usable UITableView "base class" with custom section header - swift

I have a custom table view section header (set of colored lines) that I am using in around a dozen different table views. Currently, I'm cutting and pasting the same code in every single UITableViewDelegate handler.
For example, something like this:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
let lineView = UIView(frame: CGRect(x: 40, y: 0, width: tableView.frame.width - 80, height: 1))
lineView.backgroundColor = .separator
headerView.addSubview(lineView)
return headerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 1
}
Is it possible to subclass or extend UITableView in some way so that this code is written once and automatically applied to any of my specified tableviews?

Create a class BaseVC and conform UITableViewDelegate protocol. Implement viewForHeaderInSection and heightForHeaderInSection methods in it, i.e.
class BaseVC: UIViewController, UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
let lineView = UIView(frame: CGRect(x: 40, y: 0, width: tableView.frame.width - 80, height: 1))
lineView.backgroundColor = .separator
headerView.addSubview(lineView)
return headerView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 1
}
}
Now, inherit your ViewControllers from BaseVC like so,
class VC: BaseVC, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return cell
}
}

Related

Multiple headerview in tableview in swift

I want to create 3 headers in the tableview given in the images and 8 students in each row, my code is as follows
Screenshot of the example
class ViewController: UIViewController {
var schoolOfList: [Any] = [
[["school": ["VIP", "Bright International", "Motherland"]],
[["student1": ["Chirag", "Akshay", "Shailesh", "Vishal", "Mehul", "Vinod", "Mukesh", "Darshan"]],
["student2": ["Manjari", "Kairav", "Abhimanyu", "Akshara", "Arohi", "Neel", "Naksh", "Naman"]],
["student3": ["Paritosh", "Anuj", "Kavya", "Samar", "Vanraj", "Kinjal", "Anupama", "Riyan"]]]]]
#IBOutlet weak var mytableview : UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> (Int) {
return schoolOfList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)
cell.textLabel?.text = schoolOfList["school"] as! [String]indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerview = UIView(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
headerview.backgroundColor = .green
let lable = UILabel(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
lable.textAlignment = .center
lable.text = (schoolOfList["school"]as!String)
headerview.addSubview(lable)
return headerview
}

How to add corner radius and a background to a whole section including its header and cells in UI Table View

How do I add corner radius and background to both the section header and its cell together like in the iOS weather app?
My table view data source and delegate-
extension HomeViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: HourlyForecastViewTableViewCell.identifier) else { return UITableViewCell() }
cell.layer.backgroundColor = UIColor.blue.cgColor
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
200
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return HourlyForecastHeaderView()
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
}
You can tryout this below code, here I just explained how to use UIRectCorner to apply corner radius to the specific edge.
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let kCellId = "kCellId"
var lCell = tableView.dequeueReusableCell(withIdentifier: kCellId)
if lCell == nil {
lCell = UITableViewCell(style: .default, reuseIdentifier: kCellId)
lCell?.textLabel?.text = "Row - \(indexPath.row)"
}
lCell?.backgroundColor = .orange
return lCell!
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let kHeaderId = "kHeaderId"
var header = tableView.dequeueReusableHeaderFooterView(withIdentifier: kHeaderId)
if header == nil {
header = HeaderView(reuseIdentifier: kHeaderId)
header?.frame = CGRect(origin: .zero, size: CGSize(width: tableView.bounds.size.width, height: 35))
header?.tintColor = .orange
let titleLabel = UILabel()
titleLabel.text = "Section - \(section)"
titleLabel.sizeToFit()
titleLabel.frame = CGRect(origin: CGPoint(x: 20, y: 0), size: CGSize(width: tableView.bounds.size.width-20, height: 35))
header?.addSubview(titleLabel)
}
return header
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
view.applyCorners(to: [.topLeft, .topRight], with: view.bounds)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let isLastCell = tableView.numberOfRows(inSection: indexPath.section)-1 == indexPath.row
if isLastCell {
cell.applyCorners(to: [.bottomLeft, .bottomRight], with: cell.bounds)
}else{
cell.noCorners()
}
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
50
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
35
}
}
class HeaderView: UITableViewHeaderFooterView {
}
extension UIView {
func noCorners() {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
let shape = CAShapeLayer()
shape.path = path.cgPath
layer.mask = shape
}
func applyCorners(to: UIRectCorner, with rect: CGRect) {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: to, cornerRadii: CGSize(width: 10, height: 10))
let shape = CAShapeLayer()
shape.path = path.cgPath
layer.mask = shape
}
}

How to display data correctly in spacing table view cells

Only the first element from the array is displayed in my spacing cells.
I have no problems displaying data in simple cells without spacing, but when I need spacing cells and change my code, only the first item is displayed
let test = ["1","2","3"]
func numberOfSections(in tableView: UITableView) -> Int {
return test.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
let cellSpacingHeight: CGFloat = 10
return cellSpacingHeight
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SellerPlacesCell", for: indexPath) as! SellerPlacesCell
cell.backgroundColor = UIColor.white.withAlphaComponent(0.5)
cell.namePlace.text = test[indexPath.row]
return cell
}
How to fix it?
if in
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
return 1
}
return 1
i replace return 1 to test.count have this:
Replace
cell.namePlace.text = test[indexPath.row]
with
cell.namePlace.text = test[indexPath.section]
the spacing is for the fact that you display sections , so you need to access the array with section not row

How to create multiple textfield in tableview cell dynamically

This is what I tried .....
Can anyone help me understand the below code that creates a textfield ? A summary about the following code would be very useful.
func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 4
}else if section == 1 {
return 3
}else{
return 1
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicViewController") as! DynamicTableViewCell
for var i in (0..<indexPath.count).reversed()
{
var myTextField: UITextField = UITextField(frame: CGRect(x: 0, y: 0, width: 340, height: 40))
myTextField.placeholder = "Enter Email Address \(i)"
myTextField.backgroundColor = UIColor.brown
cell.addSubview(myTextField)
}
return cell
}

How to set background colour for header in TableView?

I found similar questions, but none of them helped me.
I need to set the background colour of headers in my table to white, it is gray now(same as background colour of the table).
Here are my tableView functions:
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
{
let header = view as! UITableViewHeaderFooterView
header.backgroundColor = UIColor.white
header.textLabel?.font = UIFont(name: "Futura", size: 13)!
header.textLabel?.textColor = UIColor.blue
}
func tableView(tableView: UITableView, ViewForHeaderInSection section: Int) -> UIView? {
tableView.backgroundColor = UIColor.white
return tableView
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
{
return titles[section]
}
I'm setting background colour to white, but nothing changes.
Swift 3 - What did the trick for me was setting the header's contentView's backgroundColor.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CollapsibleTableViewHeader ?? CollapsibleTableViewHeader(reuseIdentifier: "header")
header.contentView.backgroundColor = .blueSteel
return header
}
Hope that helps someone.
Use viewForHeaderInSection method of UItableview and Create UIview
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.white
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 15
}
In Swift 3, this worked for me:
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let headerView = view as! UITableViewHeaderFooterView
headerView.textLabel?.font = UIFont(name: "Futura", size: 13)!
headerView.backgroundView?.backgroundColor = .white
}
Swift 3 below. One notable difference to previous answer, don't forget the override keyword. If you do, it won't override the function and will not work.
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.darkGray
return headerView
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 15
}