Adding Buttons to Static TableView Headers with Swift

眉间皱痕 提交于 2021-02-08 11:50:30

问题


I am trying to add UIControls to static TableViewHeaders in iOS using swift. The goal is build on top of the default appearance so the UI will match default UI elements going forward.

I found a great example of modifying the appearance of existing elements, but nothing on adding new ones.

My specific goals are:

  1. "Select All" functionality to quickly mark all rows in a section as "checked" (could be a checkmark accessory, UISwitch, etc)
  2. "Show/Hide" functionality to allow a single View to provide a simple "overview" by sections while still presenting access to details inside sections.

As both of these related to the section groupings, the headers are a logical choice for adding this functionality.


回答1:


There are two main options for customizing static headers for TableViews:

willDisplayHeaderView provides the default view and allows for modification of it. Simple appearance modifications are fairly straight forward. Adding interactive features such as buttons is a bit more complicated

viewForHeaderInSection returns the view for the header, which can be loaded from a nib or created entirely in code. One disadvantage of this is that it gives no access to the default appearance of headers, and Apple only provides access to one default (UIColor.groupTableViewBackground).

To build on top of the default header, willDisplayHeaderView needs to be used.

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
{    
    let header = view as! UITableViewHeaderFooterView
    let headerLabelFont: UIFont = header.textLabel!.font

    // References for existing or new button
    var selectButton: UIButton? = nil

    // Check for existing button
    for i in 0..<view.subviews.count {
      if view.subviews[i] is UIButton {
          selectButton = view.subviews[i] as? UIButton
      }
    }

    // No button exist, create new one
    if selectButton == nil {
      selectButton = UIButton(type: .system)
      header.addSubview(selectButton!)
      toggleButton = UIButton(type: .system)
      header.addSubview(toggleButton!)
    }
    // Configure button
    selectButton?.frame = CGRect(x: view.frame.size.width - 85, y: view.frame.size.height - 28, width: 77, height: 26)
    selectButton?.tag = section
    selectButton?.setTitle("SELECT ALL", for: .normal)
    selectButton?.titleLabel?.font = UIFont(descriptor: headerLabelFont.fontDescriptor, size: 11)
    selectButton?.contentHorizontalAlignment = .right;
    selectButton?.setTitleColor(self.view.tintColor, for: .normal)
    selectButton?.addTarget(self, action: #selector(self.selectAllInSection), for: .touchUpInside)

}

func selectAllInSection() {
    ...

The biggest challenge is working around the fact that static header cells can be reused by the TableView. So if one is modified, for example by adding a button, then when it is reused a second button could be added. This is only a problem if the TableView is large enough to scrolll off screen, but should be guarded against as the results can be tough to track down.

If multiple buttons are added to a header, some mechanism to identify each button is needed. The UIButton.tag is one option, but in this example that field is used to identify which section to act on. Another option would be to use the tag string to include two pieces of information.

A full working demo can be found on Github

(yes answering my own question, wanted to give something back after leaching for years)



来源:https://stackoverflow.com/questions/44735440/adding-buttons-to-static-tableview-headers-with-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!