12

I have a UITableView, I'm adding tableFooterView loaded from a xib.

var footer = NSBundle.mainBundle().loadNibNamed("AFooterView", owner: self, options: nil).first as! AFooterView
self.tableView.tableFooterView = footer

This works fine, but I need to be able to set the height for this footer. The xib only has a UIImageView centered vertically and horizontally so it will adapt whatever the height of the view is.

I have no clue how to do this with AutoLayout? What would be the right path to follow?

shim
  • 9,289
  • 12
  • 69
  • 108
Andres
  • 11,439
  • 12
  • 48
  • 87
  • You could add an outlet to a constraint that manages the view's height and change it's constant to be the size you want - before assigning it to the `tableFooterView` – Paul.s Jun 22 '15 at 21:24
  • Is there a reason you don't just set the height of the footer view directly in your xib? – JJC Jun 22 '15 at 21:25
  • I can't set it in the xib because the height changes, I don't know how to do that dinamically with autolayout... @JJC – Andres Jun 22 '15 at 21:26
  • 1
    You're not going to set constraints here because constraints define a relationship between two objects, and in this case you're setting the footer view directly and not adding it as a subview. If you want to control the height of the footer view, you just need adjust the height in it's frame before assigning it to `tableFooterView`. – JJC Jun 22 '15 at 21:43
  • **UIKit now works properly in 2023:** https://stackoverflow.com/a/76540476/294884 – Fattie Jun 23 '23 at 13:17
  • regarding this very old question @JJC it's now easy w/ autolayout see link – Fattie Jun 23 '23 at 13:27

2 Answers2

15

I'm sorry for the confusion, here's the updated answer:

I know you can do this by setting the frame height, but it might also work with auto layout just by re-assigning the footer view after your imageView has finished loading.

// either let auto layout calculate the frame, or set the frame yourself
// I set the width to an arbitrary size but it doesn't seem to matter, 
// it will automatically be adjusted by the tableview when you assign it
CGFloat width = 100;
CGFloat height = 500;
footerView.frame = CGRectMake(0, 0, width, height);
// this is the "trick": re-assign the footerView after its size has been updated 
// so that the tableView will show it correctly
tableView.tableFooterView = footerView;

For more information, see Resizing a UITableView’s tableHeaderView

The original answer talked about section footers, not table view footers

Velociround
  • 611
  • 7
  • 18
  • Sorry for the confusion; If you have all the constraints already setup and calculated (also works if you've set the frame height by yourself), simply re-assign your footer view to the table. The table will recognize it has a new footer and re-do whatever layout needs to occur for the proper size of the footer: `yourTableView.tableFooterView = yourFooterView;` – Velociround Jun 23 '15 at 16:12
  • I am experiencing weird behavior when rotating to landscape on iPhone, tableFooterView height become random, sometimes small sometimes huge, can't find relation – Андрей Первушин Mar 19 '19 at 14:46
  • @АндрейПервушин did you add all the required constraints? Does iOS log any warnings about your constraints, such as ambiguous, dropping some of them, or anything else? Try checking if the constraints are correct. – Velociround Mar 19 '19 at 21:35
  • All constraints are correct, had to use this workaround to fix: https://github.com/away4m/Vendors/blob/148e18cf33666fb829d3bbfb45fc8fb3cce242e0/Vendors/Extensions/UITableViewController.swift – Андрей Первушин Mar 20 '19 at 12:09
  • this extremely old answer is completely wrong, and setting fixed values has nothing to do with autolayout and does not work with it. 2023 solution https://stackoverflow.com/a/76540476/294884 – Fattie Jun 23 '23 at 13:18
-2

If you use Autolayout and load Header or Footer View from xib, you should add constraints:

func setupTableFooterView() {
    // Create your footer view from XIB and set constraints (in my case it is historyToolBarView of class HistoryToolBarView)
    let view = Bundle.main.loadNibNamed("HistoryToolBarView", owner: self, options: nil)?.first
    historyToolBarView = view as! HistoryToolBarView
    historyToolBarView.translatesAutoresizingMaskIntoConstraints = false
    historyToolBarView.addConstraints(
        [NSLayoutConstraint.init(item: self.historyToolBarView,
                                 attribute: .height,
                                 relatedBy: .equal,
                                 toItem: nil,
                                 attribute: .notAnAttribute,
                                 multiplier: 1.0,
                                 constant: 60),
         NSLayoutConstraint.init(item: self.historyToolBarView,
                                 attribute: .width,
                                 relatedBy: .equal,
                                 toItem: nil,
                                 attribute: .notAnAttribute,
                                 multiplier: 1.0,
                                 constant: UIScreen.main.bounds.size.width)])

    // Create a container of your footer view called footerView and set it as a tableFooterView
    let footerView = UIView(frame: CGRect.init(x: 0, y: 0, width: tableView.frame.width, height: 60))
    footerView.backgroundColor = UIColor.green
    tableView.tableFooterView = footerView

    // Add your footer view to the container
    footerView.addSubview(historyToolBarView)
}
Denis Kutlubaev
  • 15,320
  • 6
  • 84
  • 70
  • 3
    I don't see how this is using autolayout since the returned view is a hardcoded width and height. If this is working its simply because the footerView is not clipping bounds and the subview is overflowing the set height of 60. – Vlad Mar 31 '19 at 22:28