Search code examples
swiftuitableviewtagstableviewdelete-row

delete tableviewcell from button within inside the cell


I want my swift code to delete the tableview cell within the cell using the blue button. You can see a example of what I am trying to below in the gif. I also have a indexPath selection var. You should probably have to delete it in the deleteCell func also I assume you would use a tag. All the code is in below no need for storyboard.

enter image description here import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource, UIImagePickerControllerDelegate & UINavigationControllerDelegate {
    var arr = [1,1,3,3]
    var tableview = UITableView()
    var selectedIndexPath = IndexPath(row: 0, section: 0)
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 118
    }

   
    
    
   
    
    
    
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! customtv
      
  
     
        
        return cell
    }
    
    @objc func deleteCell(){
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        tableview.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 0.8)
      
        view.addSubview(tableview)
    

     
        tableview.register(customtv.self, forCellReuseIdentifier: "cell")
        tableview.delegate = self
        tableview.dataSource = self

      
 
        
    }
    
    
    
}

class customtv: UITableViewCell {
    lazy var backView : UIView = {
        let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width  , height: 110))
        view.backgroundColor = .green
        
        return view
    }()
    
    lazy var btn : UIButton = {
        let btn = UIButton(frame: CGRect(x: 50, y: 6, width: 100 , height: 110))
        btn.backgroundColor = .blue
        return btn
        
    }()
    
    
    
    override func layoutSubviews() {
        backView.clipsToBounds = true
        backView.frame =  CGRect(x: 0, y: 6, width: bounds.maxX  , height: 110)
        
        
    }

    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(animated, animated: true)
        addSubview(backView)
        backView.addSubview(btn)

    }
    
    
    
}

Solution

  • Here's my solution:

    import UIKit
    
    class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource, CustomTvCellDelegate, UIImagePickerControllerDelegate & UINavigationControllerDelegate {
        
        var cellCount = 2
        var tableview = UITableView()
        var selectedIndexPath = IndexPath(row: 0, section: 0)
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return cellCount // use a variable here so you can change it as you delete cells, else it will crash
        }
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 118
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTv
            cell.delegate = self
            
            return cell
        }
        
        func deleteCell(_ customTV: CustomTv, location: CGPoint) {
            
            // put the button location in an index path array
            var deleteArray = [IndexPath]()
            if let indexPath = tableview.indexPathForRow(at: location) {
                deleteArray.append(indexPath)
            }
            
            cellCount -= 1 // update the row count as you delete a cell
            
            // delete the row using the delete array with a fade animation
            tableview.deleteRows(at: deleteArray, with: .fade)
            
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            tableview.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 0.8)
          
            view.addSubview(tableview)
             
            tableview.register(CustomTv.self, forCellReuseIdentifier: "cell")
            tableview.delegate = self
            tableview.dataSource = self
        }
        
    }
    
    // you need to declare a cell delegate that will let your tableview know when the button was tapped on the cell
    protocol CustomTvCellDelegate: AnyObject {
        func deleteCell(_ customTV: CustomTv, location: CGPoint)
    }
    
    class CustomTv: UITableViewCell { // it's good form to Pascal case your class name ;)
        
        weak var delegate: CustomTvCellDelegate? // make that delegate a property of your cell
        
        lazy var backView : UIView = {
            let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width  , height: 110))
            view.backgroundColor = .green
            
            return view
        }()
        
        lazy var btn : UIButton = {
            let btn = UIButton(frame: CGRect(x: 50, y: 6, width: 100 , height: 110))
            btn.backgroundColor = .blue
           
            return btn
            
        }()
        
        override func layoutSubviews() {
            backView.clipsToBounds = true
            backView.frame =  CGRect(x: 0, y: 6, width: bounds.maxX  , height: 110)
            
            // moved these calls here instead of on setSelected(_selected:animated:)
            addSubview(backView)
            backView.addSubview(btn)
            
            btn.addTarget(self, action:#selector(self.deleteCell), for: .touchUpInside)
        }
        
        @objc func deleteCell(sender: UIButton){
            // let your cell delegate (tableview) know what the button got tapped, you need to pass the button here)
            let buttonLocation = sender.superview?.convert(sender.frame.origin, to: nil) ?? CGPoint.zero
            delegate?.deleteCell(self, location: buttonLocation)
        }
    }