title: UITableView custom section footer
body: <p>We do have a <code>TableViewModel</code> which is implementing the <code>UITableViewDelegate</code> and the <code>UITableViewDataSource</code>.  It holds the sections and returns the right rows and elements of our <code>UITableViews</code>.</p>
  
  <p>Now we want to have a custom table view section footer. Therefor we implement the <code>optional public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -&gt; UIView?</code> so that this returns a <code>UIView</code> from a xib file. This is all fine but it ends up in a wrong footer height. If we use <code>func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -&gt; String?</code> the footer is displayed correct and the height of the footer is set correct. </p>
  
  <p>So we also have to implement the <code>optional public func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -&gt; CGFloat</code> or the <code>optional public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -&gt; CGFloat</code></p>
  
  <ol>
  <li>Question: How do i get the height of an UIView which this was instantiated? <code>view.frame.bounds</code> or <code>view.frame.height</code> is always 0.</li>
  <li>Question: What is the default value Apple uses for the footer and how does it calculate that? I recognised that if we return <code>table.sectionFooterHeight</code> for the default (not our custom footer view) the hight is correct. </li>
  </ol>
  
  <p>TableViewModel:</p>
  
  <pre><code>class TableViewModel: NSObject, UITableViewDelegate, UITableViewDataSource {
  
      var sections: [TableViewSection] = []
  
      func numberOfSections(in tableView: UITableView) -&gt; Int {
          return sections.count
      }
  
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          return sections[section].numberOfRowsInTableView(tableView)
      }
  
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
          return sections[(indexPath as NSIndexPath).section].tableView(tableView, cellForRowAtIndexPath: indexPath)
      }
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          sections[(indexPath as NSIndexPath).section].tableView(tableView, didSelectRowAtIndexPath: indexPath)
      }
  
      func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -&gt; String? {
          return sections[section].headerText
      }
  
      func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
          sections[section].tableView(tableView, willDisplayHeaderView: view)
      }
  
      func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -&gt; String? {
          return sections[section].footerText
      }
  
      func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) {
          sections[section].tableView(tableView, willDisplayFooterView: view)
      }
  
      func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -&gt; Bool {
          return sections[(indexPath as NSIndexPath).section].tableView(tableView, cellContentsToCopyAtIndexPath: indexPath, withSender: nil) != nil
      }
  
      func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -&gt; CGFloat {
          ??
      }
  
      func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -&gt; UIView? {
          return sections[section].footerView
      }
  
      func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -&gt; CGFloat {
          ??
      }
  }
  </code></pre>