1

I have collapse and expand animation in UITableView. Tableview has two section in which first section data is collapse and expand. This thing perfectly working with ios 10 but in ios 11 Section view repeated or overlapped with cell data which is expanded.

Below is my code

//MARK: -Table View delegate Method
    func numberOfSections(in tableView: UITableView) -> Int {
        return read_Localizable("titleHelpSection").components(separatedBy: ",").count
    }
    //MARK: -Table View Datasource Method
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat{
        return 44.0
    }
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        var headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerView")
        let arrSection = read_Localizable("titleHelpSection").components(separatedBy: ",")
        if headerView == nil
        {
            headerView = UITableViewHeaderFooterView(reuseIdentifier: "headerView")
            headerView?.contentView.backgroundColor = UIColor.white

            let lblResult = UILabel()
            lblResult.tag = 123456
            lblResult.font = AppCommonSNMediumFont()
            lblResult.textColor = UIColor.black
            lblResult.translatesAutoresizingMaskIntoConstraints = false
            headerView?.contentView.addSubview(lblResult)

            let seperator = UIView()
            seperator.translatesAutoresizingMaskIntoConstraints = false
            seperator.backgroundColor = UIColor.black
            headerView?.contentView.addSubview(seperator)

            headerView?.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[seperator]|", options: [], metrics: nil, views: ["seperator":seperator]))

            headerView?.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[lable]-(>=8)-|", options: [], metrics: nil, views: ["lable":lblResult]))

            headerView?.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-[lable]-[seperator(1)]|", options: [], metrics: nil, views: ["lable":lblResult,"seperator":seperator]))
        }

        if let lblResult = headerView?.contentView.viewWithTag(123456) as? UILabel
        {
            lblResult.text = arrSection[section]
        }

        return headerView

    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        return UITableViewAutomaticDimension

    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 20.0
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0
        {
            return (arrHelpData.count)
        }
        else
        {
            return 1
        }
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0
        {
            var cell = tableView.dequeueReusableCell(withIdentifier: "HelpCell") as? CellHelp;
            if cell == nil {
                cell = CellHelp(style: .default, reuseIdentifier: "HelpCell")
                cell?.selectionStyle = .none
                cell?.txtContain.delegate = self
            }

            if let objModel = arrHelpData.object(at: indexPath.row) as? HelpModel
            {
                cell?.lblTitle.text = objModel.helpTitle
                if objModel.isExpanded == true
                {
                    cell?.txtContain.text = objModel.helpDesc
                }
                else
                {
                    cell?.txtContain.text = ""
                }
                cell?.imgArrow.isHighlighted = !objModel.isExpanded
            }
            return cell!
        }
        else
        {
            var cell = tableView.dequeueReusableCell(withIdentifier: "DefultCell")
            if cell == nil
            {
                cell = UITableViewCell(style: .default, reuseIdentifier: "DefultCell")
                cell?.textLabel?.textColor = color1F87A3()
                cell?.textLabel?.font = AppCommonSNRegularFont()
                cell?.selectionStyle = .none
                cell?.textLabel?.numberOfLines = 0
            }

            cell?.textLabel?.text = read_Localizable("titleSettings")
            return cell!
        }
    }



    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 0 && indexPath.row < (arrHelpData.count)
        {
            if let objModel = arrHelpData.object(at: indexPath.row) as? HelpModel
            {
                if objModel.isExpanded == true
                {
                    objModel.isExpanded = false
                }
                else
                {
                    objModel.isExpanded = true
                }
                tableView.reloadData()
            }
        }
    }

Actual view

actual view

Section overlapped on cell data

enter image description here

Chirag Shah
  • 3,034
  • 1
  • 30
  • 61

1 Answers1

0

This is very frustrating iOS11 issue, something to do around estimatedHeight issue, If you really want to keep the self sized row and header then u need to go with the below approach.

Declare variable which holds the height of the cell/header and store height into that and used it as below:

var cellHeightDictionary: NSMutableDictionary // To overcome the issue of iOS11.2

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 125
}

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cellHeightDictionary.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
}

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellHeightDictionary.object(forKey: indexPath) != nil {
        let height = cellHeightDictionary.object(forKey: indexPath) as! CGFloat
        return height
    }
    return UITableViewAutomaticDimension
}

This is the only solution which worked for me for iOS11 issues with auto sizing cells. Otherwise people suggest to keep estimatedHeight 0 to get rid off such issues. In your case first try doing this for cell and that doesn't solve the issue completely then do same for header height also. Hope this helps!

Don't forget to test in both iOS11.1 and iOS11.2.

torap
  • 656
  • 6
  • 15