title: Dropdown table view with multiple and single selection in iOS swift?
body: <p>I have filter which is done in dropdown table view in an view controller. The dropdown table view contains three section namely section 1, section 2 and section 3. For section 1 and section 3 should single selection and section 2 should be multiple selection. When tapping section 1 it expands table view cell and when tapping on section 2 will expand and section 1 will close the expansion.</p>
  
  <p>When selecting the option from each section should stored even user close and reopens the filter dropdown table view.</p>
  
  <p><strong>I have four questions:</strong></p>
  
  <ol>
  <li><p>When user tap on different section it should automatically close already open sections?</p></li>
  <li><p>Table view should adjust height and its position based number cells in each sections?</p></li>
  <li><p>how to do multiple and single selection for three sections?</p></li>
  <li><p>selected should be stored even if dropdown table view is close and reopened.</p></li>
  </ol>
  
  <p>Here is the code which tried so far all question which i have mentioned above:</p>
  
  <pre><code> extension HomeViewController : UITableViewDelegate, UITableViewDataSource, ExpandableHeaderViewDelegate {
  
  
  
  
  func numberOfSections(in tableView: UITableView) -&gt; Int {
  
      if locationListBool == true {
  
          return 1
  
      } else {
  
          return sectionss.count
  
          }
  
      }
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
      if locationListBool == true {
  
          return autocompleteplaceArray.count
  
      } else {
  
          return sectionss[section].category.count
  
        }
      }
  
  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -&gt; CGFloat {
  
      if locationListBool == true {
  
          return 0
  
      } else {
  
      return 30
  
       }
  
    }
  
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat {
  
      if locationListBool == true {
  
          return 30
  
      } else {
  
          if (sectionss[indexPath.section].expanded) {
  
  
  
             return 30
          } else  {
  
  
              return 0
  
          }
       }
  
     }
  
  func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -&gt; CGFloat {
  
      if locationListBool == true {
  
          return 0
  
      } else {
  
      return 2
  
  
      }
     }
  
  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -&gt; UIView? {
  
      if locationListBool == true {
  
          return nil
  
      } else {
  
      let header = ExpandableHeaderView()
      header.contentView.backgroundColor = UIColor.white
      header.customInit(title: sectionss[section].genre, section: section, delegate: self)
  
  
      return header
  
      }
      }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  
      if locationListBool == true {
              let cell = tableView.dequeueReusableCell(withIdentifier: "placecell", for: indexPath) as! locationNameTableViewCell
  
              guard autocompleteplaceArray.count &gt; 0 else {
  
                  return cell
              }
  
              cell.locationName.text = autocompleteplaceArray[indexPath.row]
  
  
  
              return cell
  
      } else {
  
      let cell = dropDownTbl.dequeueReusableCell(withIdentifier: "dropDownCell", for: indexPath) as! dropDownCell
  
      cell.dropDownLbl.text = sectionss[indexPath.section].category[indexPath.row]
      cell.selectionStyle   = .none
  
      return cell
  
      }
  
      }
  
  
     func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
  
  
  
    }
  
  
  func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
  
      cell.backgroundColor = UIColor.clear
  
      if locationListBool == true {
  
          let lastRowIndex = tableView.numberOfRows(inSection: 0)
          if indexPath.row == lastRowIndex - 1  {
  
              tableView.allowsSelection = true
  
          } else {
  
              tableView.allowsSelection = true
          }
  
          }
  
       }
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          if locationListBool == true {
  
          if let indexPath = tableView.indexPathForSelectedRow  {
  
              let currentCell = tableView.cellForRow(at: indexPath) as! UITableViewCell
              searchText.text = (currentCell.textLabel?.text)
              searchText.text = autocompleteplaceArray[indexPath.row]
              placeIDString = autocompletePlaceIDArray[indexPath.row]
              print("placeIDString::::\(String(describing: placeIDString))")
  
              if placeIDString != nil {
  
                  getPlaceIDLatLong(placeIDs: placeIDString!)
                  print("get lat long \(getPlaceIDLatLong(placeIDs: placeIDString!))")
  
              }
  
        //            PrefsManager.sharedinstance.lastlocation = searchText.text
              locationText = searchText.text
              print("locationText::::\(String(describing: locationText))")
  
              }
  
  
          self.locationTableList.isHidden = true
  
          }
          else {
  
  
          }
  
      }
  
  
  func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -&gt; IndexPath? {
  
      switch indexPath.section {
      case 0:
          if let previousIndexPath = indexPathOfSelectedRowPaidBy {
              dropDownTbl.deselectRow(at: previousIndexPath as IndexPath, animated: false)
              dropDownTbl.cellForRow(at: previousIndexPath as IndexPath)?.accessoryType = UITableViewCellAccessoryType.none
          }
          indexPathOfSelectedRowPaidBy = indexPath as NSIndexPath?
          dropDownTbl.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
  
      case 1:
  
          dropDownTbl.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.checkmark
  
  
      default:
  
          break
      }
  
      return indexPath
     }
  
  func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
    {
  
      switch indexPath.section {
  
      case 0:
  
          if let previousIndexPath = indexPathOfSelectedRowPaidBy {
              dropDownTbl.deselectRow(at: previousIndexPath as IndexPath, animated: false)
              dropDownTbl.cellForRow(at: previousIndexPath as IndexPath)?.accessoryType = UITableViewCellAccessoryType.none
          }
          indexPathOfSelectedRowPaidBy = nil
  
      case 1:
          dropDownTbl.cellForRow(at: indexPath)?.accessoryType = UITableViewCellAccessoryType.none
  
  
  
  
      default:
  
          break
      }
  
    }
  
  
  func toogleSection(header: ExpandableHeaderView, section: Int) {
      sectionss[section].expanded = !sectionss[section].expanded
      dropDownTbl.beginUpdates()
  
      if sectionss[0].expanded{
  
  
          dropDownTbl.layer.frame = CGRect(x: 15, y: 152, width: 345, height: 300)
  
      } else if sectionss[1].expanded  {
  
  
          dropDownTbl.layer.frame = CGRect(x: 15, y: 152, width: 345, height: 230)
  
      } else if sectionss[2].expanded {
  
          dropDownTbl.layer.frame = CGRect(x: 15, y: 152, width: 345, height: 330)
  
      } else {
  
          dropDownTbl.layer.frame = CGRect(x: 15, y: 152, width: 345, height: 90)
      }
  
      for i in 0 ..&lt; sectionss[section].category.count {
  
  
  
              dropDownTbl.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
  
      }
      dropDownTbl.endUpdates()
  }
  }
  </code></pre>
  
  <p><strong>Expandable table view header::</strong></p>
  
  <pre><code> import UIKit
  
  protocol ExpandableHeaderViewDelegate {
  func toogleSection(header: ExpandableHeaderView, section: Int)
   }
  
   class ExpandableHeaderView: UITableViewHeaderFooterView {
  
  var delegate: ExpandableHeaderViewDelegate?
  var section: Int!
  var collapaseHandlerArray = [String]()
  
  let button = UIButton()
  let button2 = UIButton()
  
  override init(reuseIdentifier: String?){
      super.init(reuseIdentifier: reuseIdentifier)
      self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(selectheaderAction)))
   }
  
  required init?(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
   }
  
  @objc func selectheaderAction(gestureRecognizer: UITapGestureRecognizer) {
  
      let cell = gestureRecognizer.view as! ExpandableHeaderView
  
  
     }
  
     func customInit(title: String, section: Int, delegate: ExpandableHeaderViewDelegate) {
  
  
      self.textLabel?.text = title
  
  
  
  
      self.section = section
      self.delegate = delegate
  
    }
  
  override func layoutSubviews() {
      super.layoutSubviews()
  
      self.textLabel?.font = UIFont(name: "Nunito-Light", size: 12)
      self.textLabel?.textColor = UIColor(red: 64.0/255, green: 75.0/255, blue: 105.0/255, alpha: 1.0)
      self.contentView.backgroundColor = UIColor.white
  
  }
  
   }
  </code></pre>
  
  <p><strong>Dropdown table view cell:</strong></p>
  
  <pre><code> class dropDownCell: UITableViewCell {
  
  @IBOutlet weak var dropDownLbl: UILabel!
  @IBOutlet weak var dropDwnBtn: UIButton!
  
  override func awakeFromNib() {
      super.awakeFromNib()
      // Initialization code
  }
  
  override func setSelected(_ selected: Bool, animated: Bool) {
      super.setSelected(selected, animated: animated)
  
      // Configure the view for the selected state
  }
  
  }
  </code></pre>
  
  <p>Here is the screen shots when selection done in cell and after reopen filter selections are removed or options selected are changed, sections are not closed already expanded sections. Excepted result: <a href="https://i.stack.imgur.com/CYZeW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/CYZeW.png" alt="section with selected"></a><a href="https://i.stack.imgur.com/RRzNi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RRzNi.png" alt="section2 selected with multiple option"></a><a href="https://i.stack.imgur.com/ia2P3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ia2P3.png" alt="section3 with selected with single selection"></a></p>