我的应用程序创建了一个UITableViewController,它包含一个可能具有任意高度的自定义tableHeaderView.我一直在努力设置动态设置此标头,因为似乎建议的方法是缩短此标头.我的UITableViewController的相关代码:
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() } } }
这会导致以下错误的布局:
如果我改变路线:tableHeader.frame = CGRectMake(0, 0, width, height)
到tableHeader.frame = CGRectMake(0, 0, width, 1000)
了tableHeaderView将自己正确的布局:
我不确定我在这里做错了什么.另外,自定义UIView类,如果这有帮助:
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 } }
TravMatth.. 79
复制自这篇文章.(如果您正在寻找更多细节,请务必看到它)
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 } } }
Nathan Hosse.. 10
更简洁的OP的答案,有利于允许布局自然发生(注意此解决方案使用视图将 LayoutSubviews):
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if let header = tableView.tableHeaderView { let newSize = header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) header.frame.size.height = newSize.height } }
如图所示,Apple没有理由不支持自动表格视图页眉/页脚高度,因为它们现在使用单元格.令人沮丧.
感谢TravMatth的原始答案.
复制自这篇文章.(如果您正在寻找更多细节,请务必看到它)
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 } } }
更简洁的OP的答案,有利于允许布局自然发生(注意此解决方案使用视图将 LayoutSubviews):
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if let header = tableView.tableHeaderView { let newSize = header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) header.frame.size.height = newSize.height } }
如图所示,Apple没有理由不支持自动表格视图页眉/页脚高度,因为它们现在使用单元格.令人沮丧.
感谢TravMatth的原始答案.
使用确定标题的帧大小
header.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
当我的标题视图由单个多行标签组成时,上面的答案中的建议对我不起作用.将标签的换行模式设置为换行,文本将被切断:
相反,对我有用的是使用表视图的宽度和0的高度作为目标大小:
header.systemLayoutSizeFitting(CGSize(width: tableView.bounds.width, height: 0))
把它们放在一起(我更喜欢使用扩展名):
extension UITableView { func updateHeaderViewHeight() { if let header = self.tableHeaderView { let newSize = header.systemLayoutSizeFitting(CGSize(width: self.bounds.width, height: 0)) header.frame.size.height = newSize.height } } }
并称之为:
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() tableView.updateHeaderViewHeight() }