iosswiftuitableviewcollapsable

Swift: UITableView row items not hiding when hide that row


I have a table view class and three cell classes which I am using to populate 3 rows of table view.screenshot of my table view

I want to hide 2nd row whenever toggle button is off. when I tap on the toggle button the row gets collapsed but the cell item does not hide.scrrenshot after tapping toggle button

here is my code:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row==0{
            let cell=tableView.dequeueReusableCell(withIdentifier: "cellid", for: indexPath) as! toggleCell
            return cell

        }
        if indexPath.row==1{
            let cell1=tableView.dequeueReusableCell(withIdentifier: "cellid2", for: indexPath) as! oneButtonCell
            cell1.layer.backgroundColor=UIColor.purple.cgColor
            return cell1
        }
        else{
            let cell1=tableView.dequeueReusableCell(withIdentifier: "cellid1", for: indexPath)
            cell1.layer.backgroundColor=UIColor.green.cgColor
            return cell1
        }
    }
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row==1{
            if istoggleOn==true{
                return 75
            }
            else{
            return 0
            }
        }
        else{
            return 75
        }
    }
}
class CellBase: UITableViewCell{
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style:style,reuseIdentifier:reuseIdentifier)
        setupViews()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func setupViews(){
        backgroundColor=UIColor.green
    }
}
class toggleCell:CellBase{

    let containerView=UIView()
    let label:UILabel={
        let label=UILabel()
        label.text="Toggle Button"
        label.textColor = .black
        label.font=UIFont.init(name: "HelveticaNeue-Bold", size: 20)
        return label
    }()
    lazy var button:UISwitch={
            let toggle=UISwitch()
            toggle.isOn=true
            toggle.onTintColor=UIColor(red: 59/255, green: 178/255, blue: 250/255, alpha: 1)
            toggle.addTarget(self, action: #selector(handleToggleAction), for: .valueChanged)
            return toggle
        }()
    @objc func handleToggleAction(sender:UISwitch){
         let parent = self.parentViewController as! ViewController

        if sender.isOn{
            print("on")
            parent.istoggleOn=true
            parent.tableView.beginUpdates()
            parent.tableView.endUpdates()
        }
        else{
            print("off")
            parent.istoggleOn=false
            parent.tableView.beginUpdates()
            parent.tableView.endUpdates()
        }
    }
    override func setupViews(){
    addSubview(containerView)
    setupContainerView()

    addConstraintsWithFormat(format: "H:|-20-[v0]-20-|", views: containerView)
    addConstraintsWithFormat(format: "V:|-15-[v0]-15-|", views: containerView)
}
    func setupContainerView(){
}
class oneButtonCell:CellBase{
    let containerView:UIView={
        let view=UIView()
        view.layer.cornerRadius=10
        view.layer.borderColor=UIColor(red: 59/255, green: 178/255, blue: 250/255, alpha: 1).cgColor
        view.layer.borderWidth=2
        return view
    }()
    let label:UILabel={
        let label=UILabel()
        label.text="SomeText"
        label.textColor = .black
        label.font=UIFont.init(name: "HelveticaNeue-Bold", size: 20)
        return label
    }()
    lazy var button:UIButton={
           let button=UIButton()
            button.setTitle("Button", for: .normal)
            button.titleLabel?.font=UIFont.init(name: "HelveticaNeue-Bold", size: 20)
            button.titleLabel?.adjustsFontSizeToFitWidth = true
            button.titleLabel?.minimumScaleFactor = 0.5
            button.setTitleColor(UIColor(red: 59/255, green: 178/255, blue: 250/255, alpha: 1), for: .normal)
            let image=UIImage(named: "arrow")?.withRenderingMode(.alwaysTemplate)
            button.setImage(image, for: .normal)
            button.imageView?.tintColor = .gray
            button.semanticContentAttribute = .forceRightToLeft
            button.addTarget(self, action: #selector(preferenceMenu), for: .touchUpInside)
            return button
        }()
    @objc func preferenceMenu(sender:UIButton){
        print("drop")
    }
    override func setupViews(){
        addSubview(containerView)
        setupContainerView()

        addConstraintsWithFormat(format: "H:|-20-[v0]-20-|", views: containerView)
        addConstraintsWithFormat(format: "V:|-15-[v0(45)]-15-|", views: containerView)
    }
    func setupContainerView(){
}
}

I am doing everything programmatically. please help me how I can achieve this


Solution

  • The cell's contents are showing because you made the row-height 0... but this approach for showing/hiding a row (and the way you have setup your views) doesn't change the content of that cell.

    So, the content is still showing because it is extending below the bounds of the cell.

    There are other (arguably better) ways of showing/hiding rows, but sticking with your approach...

    Change your setupViews() func in class CellBase to:

    func setupViews(){
    
        // add this line
        self.clipsToBounds = true
    
        backgroundColor=UIColor.green
    
    }
    

    Edit

    Since the code from the original post was not complete, I forgot to note that each custom cell class should probably be including a call to super in its setupViews() func:

    override func setupViews(){
        // adding this line will allow you to put common setup tasks
        // in the setupViews() func in CellBase class
        super.setupViews()
    
        // do additional setup tasks that are specific to this cell class
        addSubview(containerView)
        setupContainerView()
    
        addConstraintsWithFormat(format: "H:|-20-[v0]-20-|", views: containerView)
        addConstraintsWithFormat(format: "V:|-15-[v0]-15-|", views: containerView)
    }