Friday, March 10, 2017

Resize table header when using dynamic types

Leave a Comment

I have a TableViewController with a header. This header is a container, which links to another storyboard named Header.storyboard

TableViewController

Header.storyboard contains a stack view with some labels, that are dynamically typed.

Labels text comes from DB.

No regards to the text dimension or size I want to visualise it correctly.

enter image description here

I've used some answers from SO to get the header correctly resize, but without luck:

import UIKit  class TableViewController: UITableViewController {      @IBOutlet weak var tableHeaderView: UIView!      override func viewDidLayoutSubviews() {         super.viewDidLayoutSubviews()          // Dynamic sizing for the header view         if let headerView = tableHeaderView {             headerView.setNeedsLayout()             headerView.layoutIfNeeded()              let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height             var headerFrame = headerView.frame              // If we don't have this check, viewDidLayoutSubviews() will get             // repeatedly, causing the app to hang.             if height != headerFrame.size.height {                 headerFrame.size.height = height                 headerView.frame = headerFrame                 tableHeaderView = headerView            }        }    } } 

3 Answers

Answers 1

try to implement

tableView(_ tableView: UITableView, heightForHeaderInSection section: Int)  

and

tableView(_ tableView: UITableView, viewForHeaderInSection section: Int)
your code should look like this :

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {     return tableHeaderView.bounds.size.height }  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {     return tableHeaderView } 

Answers 2

Table view header can be automatically resized

but with containers it likely will not work

use custom view instead for viewForHeaderInSection

class ViewController: UITableViewController {     override func viewDidLoad() {         tableView.estimatedSectionHeaderHeight = 10         tableView.sectionHeaderHeight = UITableViewAutomaticDimension     }     override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {         let lab = UILabel()         lab.text = "text \(section)"         lab.font = UIFont.systemFont(ofSize: 10 * CGFloat(section) + 1)         return lab     }     override func numberOfSections(in tableView: UITableView) -> Int {         return 5     }     //this method overriding is not necessary     override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {         return UITableViewAutomaticDimension     } } 

Result

Answers 3

First, instead of giving the height to the view, you should give the label a height

class ViewController : UITableViewController {  override func viewDidLoad() {     super.viewDidLoad()     // Do any additional setup after loading the view, typically from a nib. }  override func didReceiveMemoryWarning() {     super.didReceiveMemoryWarning()     // Dispose of any resources that can be recreated. }  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {     return 40 }  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {     return 4 }  override func numberOfSections(in tableView: UITableView) -> Int {     return 1 }  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)      cell.backgroundColor = UIColor.yellow     cell.textLabel?.text = "Baran"      return cell  }  override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {     return heightForView() }  override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {     let headerView : UIView = UIView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width, height: self.heightForView()))     headerView.backgroundColor = UIColor.black      let label : UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.heightForView()))     label.numberOfLines = 0     label.textAlignment = NSTextAlignment.center     label.text = "Size To Fit Tutorial"     label.font = UIFont(name: "Helvetica", size: 50)     label.textColor = UIColor.white     headerView.addSubview(label)      return headerView }  //Self Sizing height .... func heightForLabel(text:String, font:UIFont, width:CGFloat) -> CGFloat{     let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))     label.numberOfLines = 0     label.lineBreakMode = NSLineBreakMode.byCharWrapping     label.font = font     label.text = text     label.sizeToFit()     return label.frame.height }  func heightForView() -> CGFloat{      let screenSize = UIScreen.main.bounds     let screenWidth = screenSize.width      let text = "Size To Fit Tutorial"     let font : UIFont!     switch UIDevice.current.userInterfaceIdiom {     case .pad:         font = UIFont(name: "Helvetica", size: 35)     case .phone:         font = UIFont(name: "Helvetica", size: 50)     default:         font = UIFont(name: "Helvetica", size: 24)     }     let height = heightForLabel(text: text, font: font, width: screenWidth)      return height } } 

enter image description here

Hope this helps

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment