I realize a number of questions have been asked surrounding this topic. But I am wondering what the preferred way of globally within an app changing the display or format of a section header. Can a subclass of Section be made effectively?
I have used the custom UIView (.Class) option of the HeaderFooterView but am not sure at this point how I can set up internal views of this custom view that are customizable... like section title, etc. Is there a way to do this within the onSetupView callback?
Any examples would be super helpful. Thanks
It's up to you to subclass Section class.
Here is an example of autosized header text....
class HomeViewController : FormViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView?.estimatedSectionHeaderHeight = 40 // without this line the autosize doesn't work.
form +++=
MySection("This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title") { _ in }
<<< ButtonRow() { (row: ButtonRow) -> Void in
row.title = "About"
} .onCellSelection({ [weak self] (cell, row) in
let mySection = row.section?.form?[0] as? MySection
mySection?.myHeaderString = mySection?.myHeaderString == "aaaaaaaaa" ? "This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title, This is a very very very long title": "aaaaaaaaa"
self?.tableView?.beginUpdates()
self?.tableView?.endUpdates()
})
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView?.beginUpdates()
tableView?.endUpdates()
}
class MySection: Section {
var myHeaderString: String? {
didSet {
let view = header?.viewForSection(self, type: .Header)
view?.setNeedsLayout()
}
}
override init(_ header: String, @noescape _ initializer: Section -> ()) {
myHeaderString = header
super.init(header, initializer)
var header = HeaderFooterView<AutoSizeLabelView>(.Class)
header.height = { UITableViewAutomaticDimension }
header.onSetupView = { v, s in
v.label.text = (s as? MySection)?.myHeaderString
}
self.header = header
}
required init(@noescape _ initializer: Section -> ()) {
var header = HeaderFooterView<AutoSizeLabelView>(.Class)
header.height = { UITableViewAutomaticDimension }
header.onSetupView = { v, s in
v.label.text = (s as? MySection)?.myHeaderString
}
super.init(initializer)
}
required init() {
var header = HeaderFooterView<AutoSizeLabelView>(.Class)
header.height = { UITableViewAutomaticDimension }
header.onSetupView = { v, s in
v.label.text = (s as? MySection)?.myHeaderString
}
super.init()
}
}
}
class AutoSizeLabelView: UIView {
lazy var label: UILabel = {
var result = UILabel()
result.translatesAutoresizingMaskIntoConstraints = false
result.numberOfLines = 0
return result
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(label)
addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[label]-|", options: NSLayoutFormatOptions.AlignAllBaseline, metrics: nil, views: ["label": label]))
addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[label]-|", options: NSLayoutFormatOptions.AlignAllLeft, metrics: nil, views: ["label": label]))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
label.preferredMaxLayoutWidth = frame.size.width
superview?.setNeedsLayout()
}
}
Here is the result...

Ideally for autosized headers it would be better to use a nib file to define the header view and its constraints.
tableView?.reloadData()can be used instead ofbeginUpdate()andendUpdate()in case you are not interested in animating the transition.
onSetupView is called each time the header/footer appears on the screen, I mean whenever any of these table view delegate methods are invoked...
public func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
public func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
Based on that, onSetupView must not be used to change header/footer subviews hierarchy, it's a good place to set up view properties such as fonts, colors, text, etc.
Most helpful comment
It's up to you to subclass
Sectionclass.Here is an example of autosized header text....
Here is the result...
onSetupViewis called each time the header/footer appears on the screen, I mean whenever any of these table view delegate methods are invoked...Based on that,
onSetupViewmust not be used to change header/footer subviews hierarchy, it's a good place to set up view properties such as fonts, colors, text, etc.