Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting tableHeaderView height dynamically

My application creates a UITableViewController that contains a custom tableHeaderView which may have an arbitrary height. I've been struggling with a way to set this header dynamically, as it seems the suggested ways have been cutting this header short. My UITableViewController's relevant code:

import UIKit import SafariServices  class RedditPostViewController: UITableViewController, NetworkCommunication, SubViewLaunchLinkManager {      //MARK: UITableViewDataSource     var post: PostData?     var tree: CommentTree?     weak var session: Session! = Session.sharedInstance      override func viewDidLoad() {         super.viewDidLoad()          // Get post info from api         guard let postData = post else { return }          //Configure comment table         self.tableView.registerClass(RedditPostCommentTableViewCell.self, forCellReuseIdentifier: "CommentCell")         let tableHeader = PostView(withPost: postData, inViewController: self)        let size = tableHeader.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize)        let height = size.height        let width = size.width        tableHeader.frame = CGRectMake(0, 0, width, height)        self.tableView.tableHeaderView = tableHeader          session.getRedditPost(postData) { (post) in            self.post = post?.post            self.tree = post?.comments            self.tableView.reloadData()        }     } } 

This results in the following incorrect layout:

If I change the line: tableHeader.frame = CGRectMake(0, 0, width, height) to tableHeader.frame = CGRectMake(0, 0, width, 1000) the tableHeaderView will lay itself out correctly:

I'm not sure what I'm doing incorrectly here. Also, custom UIView class, if this helps:

import UIKit import Foundation  protocol SubViewLaunchLinkManager: class {     func launchLink(sender: UIButton) }  class PostView: UIView {      var body: UILabel?     var post: PostData?     var domain: UILabel?     var author: UILabel?     var selfText: UILabel?     var numComments: UILabel?      required init?(coder aDecoder: NSCoder) {         fatalError("Not implemented yet")     }      init(withPost post: PostData, inViewController viewController: SubViewLaunchLinkManager) {         super.init(frame: CGRectZero)          self.post = post         self.backgroundColor = UIColor.lightGrayColor()          let launchLink = UIButton()         launchLink.setImage(UIImage(named: "circle-user-7"), forState: .Normal)         launchLink.addTarget(viewController, action: "launchLink:", forControlEvents: .TouchUpInside)         self.addSubview(launchLink)          selfText = UILabel()         selfText?.backgroundColor = UIColor.whiteColor()         selfText?.numberOfLines = 0         selfText?.lineBreakMode = .ByWordWrapping         selfText!.text = post.selfText         self.addSubview(selfText!)         selfText?.sizeToFit()          //let attributedString = NSAttributedString(string: "Test"/*post.selfTextHtml*/, attributes: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType])         //selfText.attributedText = attributedString          body = UILabel()         body!.text = post.title         body!.numberOfLines = 0         body!.lineBreakMode = .ByWordWrapping         body!.textAlignment = .Justified         self.addSubview(body!)          domain = UILabel()         domain!.text = post.domain         self.addSubview(domain!)          author = UILabel()         author!.text = post.author         self.addSubview(author!)          numComments = UILabel()         numComments!.text = "\(post.numComments)"         self.addSubview(numComments!)          body!.translatesAutoresizingMaskIntoConstraints = false         domain!.translatesAutoresizingMaskIntoConstraints = false         author!.translatesAutoresizingMaskIntoConstraints = false         selfText!.translatesAutoresizingMaskIntoConstraints = false         launchLink.translatesAutoresizingMaskIntoConstraints = false         numComments!.translatesAutoresizingMaskIntoConstraints = false          let views: [String: UIView] = ["body": body!, "domain": domain!, "author": author!, "numComments": numComments!, "launchLink": launchLink, "selfText": selfText!]         //let selfTextSize = selfText?.sizeThatFits((selfText?.frame.size)!)         //print(selfTextSize)         //let metrics = ["selfTextHeight": selfTextSize!.height]                     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[domain]-|", options: [], metrics: nil, views: views))        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[author]-|", options: [], metrics: nil, views: views))     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[numComments]-|", options: [], metrics: nil, views: views))     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[launchLink]-[numComments]-|", options: [], metrics: nil, views: views))     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[body][launchLink]|", options: [], metrics: nil, views: views))     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[selfText][launchLink]|", options: [], metrics: nil, views: views))     self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[domain][author][numComments][launchLink]|", options: [], metrics: nil, views: views)) }  override func layoutSubviews() {     super.layoutSubviews()     body?.preferredMaxLayoutWidth = body!.bounds.width } } 
like image 512
TravMatth Avatar asked Jan 07 '16 17:01

TravMatth


1 Answers

Copied from this post. (Make sure you see it if you're looking for more details)

override func viewDidLayoutSubviews() {     super.viewDidLayoutSubviews()      if let headerView = tableView.tableHeaderView {          let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height         var headerFrame = headerView.frame          //Comparison necessary to avoid infinite loop         if height != headerFrame.size.height {             headerFrame.size.height = height             headerView.frame = headerFrame             tableView.tableHeaderView = headerView         }     } } 
like image 65
TravMatth Avatar answered Oct 11 '22 09:10

TravMatth