2016-01-07 7 views
10

मेरा एप्लिकेशन एक UITableViewController बनाता है जिसमें एक कस्टम तालिका हैडर व्यू जिसमें मनमाने ढंग से ऊंचाई हो सकती है। मैं इस हेडर को गतिशील रूप से सेट करने के तरीके से संघर्ष कर रहा हूं, क्योंकि ऐसा लगता है कि सुझाए गए तरीके इस हेडर को कम कर रहे हैं। मेरे 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() 
     } 
    } 
} 

यह निम्न गलत लेआउट में परिणाम: enter image description here अगर मैं लाइन बदलने के लिए: tableHeader.frame = CGRectMake(0, 0, width, height)tableHeader.frame = CGRectMake(0, 0, width, 1000) को tableHeaderView ही बाहर सही ढंग से रखना होगा: enter image description here

मैं यकीन नहीं है कि मैं यहाँ गलत तरीके से क्या कर रहा हूं। इसके अलावा, कस्टम 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 
} 
} 

उत्तर

35
//Dynamically determine the height of the tableHeaderView -> this code was the result of much effort. 
//http://collindonnell.com/2015/09/29/dynamically-sized-table-view-header-or-footer-using-auto-layout/ 
override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    if let headerView = tableView.tableHeaderView { 

     let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).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 
     } 
    } 
} 
+0

बहुत बढ़िया काम प्रिय पर सही ढंग से काम है !! –

+0

कैपो, ग्रेसीस। धन्यवाद। –

+0

अंतिम पंक्ति तालिका के बिना View.tableHeaderView = headerView काम नहीं करता है। @TravMatth, क्या आप मुझे समझा सकते हैं कि हमें tableView.tableHeaderView को फिर से असाइन क्यों करना है? – Giorgio

-1

अधिक (लेआउट स्वाभाविक रूप से होने के लिए अनुमति के लाभ के साथ) ओ पी के जवाब का संक्षिप्त संस्करण:

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    if let header = tableView.tableHeaderView { 
     let newSize = header.systemLayoutSizeFitting(UILayoutFittingCompressedSize) 
     header.frame.size.height = newSize.height 
    } 
} 

कार्यान्वयन पता चलता है, ऐप्पल के लिए स्वचालित तालिका दृश्य शीर्षलेख/पाद लेख ऊंचाइयों का समर्थन नहीं करने के लिए कोई बहाना नहीं है क्योंकि वे अब कोशिकाओं के साथ करते हैं। निराशा होती।

मूल उत्तर के लिए TravMatth के लिए धन्यवाद।

+0

मुझे यकीन नहीं है कि क्यों, लेकिन यह मेरे लिए काम नहीं करता था, लेकिन ओपी जवाब ने किया। – Harris

+0

इसकी वजह यह है कि 'tableView.tableHeaderView.frame.size.height' केवल पढ़ने के लिए है। आपको फ्रेम 'tableView.tableHeaderView.frame = ...' सेट करना होगा। – mrcl

+0

मुझे यह भी यकीन नहीं है कि यह आपके लिए @ हारिस क्यों नहीं काम करता है। CGSize ऊंचाई/चौड़ाई गुण अब केवल पढ़ने के लिए नहीं हैं, इसलिए यह कारण नहीं होना चाहिए। अगर कोई इस समाधान के साथ अपने मुद्दे में अंतर्दृष्टि प्रदान करता है तो मुझे निदान में मदद करने में खुशी होगी क्योंकि मैं अभी भी इसके साथ खड़ा हूं। –

0

यदि आपको अभी भी उपरोक्त कोड नमूने के साथ लेआउट के साथ समस्याएं आ रही हैं, तो कस्टम हेडर व्यू पर translatesAutoresizingMaskIntoConstraints अक्षम करने का एक मामूली मौका है। उस स्थिति में, आपको हेडर के फ्रेम को सेट करने के बाद translatesAutoresizingMaskIntoConstraints को true पर सेट करने की आवश्यकता है।

यहाँ कोड नमूना मैं उपयोग कर रहा हूँ, और iOS 11.

public override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    guard let headerView = tableView.tableHeaderView else { return } 

    let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height 
    var headerFrame = headerView.frame 

    if height != headerFrame.size.height { 
     headerFrame.size.height = height 
     headerView.frame = headerFrame 
     tableView.tableHeaderView = headerView 

     if #available(iOS 9.0, *) { 
      tableView.layoutIfNeeded() 
     } 
    } 

    headerView.translatesAutoresizingMaskIntoConstraints = true 
} 
संबंधित मुद्दे