Ashish Bhatnagar
Ashish Bhatnagar

Reputation: 1

Adding swipe button in table view in swift

I have a simple table view showing a list of tasks. I want to show two buttons when user swipes on a cell. A delete button to delete the cell and Completed button to store the task in completed array. I am able to implement the delete button but no idea of showing a second button in the table cell. here is the code.

import UIKit

var taskArray = [String]()
var datesArray = [String]()

class ViewController: UIViewController, UITableViewDataSource
{
    @IBOutlet weak var taskTableView: UITableView!

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return taskArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row + 1). \(taskArray[indexPath.row])"
        cell.detailTextLabel?.text = datesArray[indexPath.row]
        return cell
    }


    override func viewDidLoad()
    {
        super.viewDidLoad()
        taskTableView.dataSource = self
        let userDefaults = UserDefaults.standard
        if let task = userDefaults.stringArray(forKey: "tasks") , let date = userDefaults.stringArray(forKey: "dates")
        {
            taskArray = task
            datesArray = date
        }

        print(taskArray)
        print(datesArray)
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        taskTableView.reloadData()
    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // this method handles row deletion
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
    {

        if editingStyle == .delete
        {

            // remove the item from the data model
            taskArray.remove(at: indexPath.row)
            datesArray.remove(at: indexPath.row)

            // delete the table view row
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }

    //function to come back from close button
    @IBAction func close(segue: UIStoryboardSegue)
    {

    }
}

Upvotes: 0

Views: 4395

Answers (5)

Badal Shah
Badal Shah

Reputation: 7602

As par your Requirement i have . created Demo for you.

Here is the Output,

enter image description here

When you press Delete element will be removed from Array and when you press Add Button element will be added to new Array.

Here is the link of Demo, Tableview Demo with Swipable Add and Delete

Step 1:- Connect your Tableview datasource and delegate in Storyboard.

Step 2:- Write DataSource Methods of TableView.

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if section == 0 {
            return "Preloaded Data"
        } else {
            return "Added Data to New Array"
        }
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return arrPrelodedData.count
        } else {
            return arrAddNewData.count
        }

    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard  let cell = tableView.dequeueReusableCell(withIdentifier: "SwipeToDelete", for: indexPath) as? SwipeToDelete else {return UITableViewCell()}
        if indexPath.section == 0{
            cell.lblCellContent.text = arrPrelodedData[indexPath.row] }
        else {
            cell.lblCellContent.text = arrAddNewData[indexPath.row]
        }

        return cell
    }
    //With this we can edit UITableview ex. Swipe to Delete
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        if indexPath.section == 0 {
            return true } else {
            return false
        }
    }

    //Select tableview Editing Style (insert and Delete)-> if custom icon than set None
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
        return UITableViewCellEditingStyle.none
    }




    //Delete Action 1) Create delete Action 2) Remove data with Indexpath 3) fetch data from coredata 4) delete tableview row 4) set delete button background color 5) return deleteAction in arry wether it is single
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        //Destructive Because we want to delete(destroy) the data from tableview
        let deleteAction = UITableViewRowAction(style: .destructive, title: "DELETE") { (rowAction, indexpath) in
            self.arrPrelodedData.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexpath], with: .automatic)
        }

        let addAction = UITableViewRowAction(style: .normal, title: "ADD 1") { (rowAction, indexpath) in
            self.arrAddNewData.append(self.arrPrelodedData[indexPath.row])
            tableView.reloadSections(NSIndexSet(index: 1) as IndexSet, with: .none)


           // tableView.reloadRows(at: [indexPath], with: .automatic)

        }
        deleteAction.backgroundColor = #colorLiteral(red: 1, green: 0.1491314173, blue: 0, alpha: 1)
        addAction.backgroundColor = #colorLiteral(red: 0.9176470588, green: 0.662745098, blue: 0.2666666667, alpha: 1)
        return [deleteAction,addAction]
}
}

I hope this answer will helpful for you.

Upvotes: 0

Serhii Stakhiv
Serhii Stakhiv

Reputation: 1026

Swift 4.0

  1. Add Delegate & DataSource

    tableView.delegate = self
    tableView.dataSource = self
    
  2. Add DataSource func "canEditRowAt indexPath"

    //MARK: - UITableViewDataSource
    public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
  3. Add Delegate func "editActionsForRowAt indexPath"

    //MARK: - UITableViewDelegate
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    
    
        let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
            //Action edit
            print("Action Edit...")
        })
    
        editAction.backgroundColor = UIColor.gray //Set button color
    
        let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
            //Action delete
            print("Action Delete...")
        })
    
        return [deleteAction, editAction]
    }
    

I hope this helps.

Upvotes: 0

Rishabh Shukla
Rishabh Shukla

Reputation: 501

First make this function return true

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
{
    return true
}

it makes your cell editable , apple provides default deleting and editing options that you can use as like this :

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {


    if(editingStyle == .delete)
    {
        myArray.remove(at: indexPath.item)
        table.deleteRows(at: [indexPath], with: .automatic)
        table.reloadData()

    }

}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {

   if(studentUser as? String == "Admin")
    {
        return .delete
    }
    else
    {
        return .none
    }
}

or you can define your custom ones :

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
{
    let del = UITableViewRowAction(style: .normal, title: "Delete")
    {
        (action, index) in

        let alert = FCAlertView()
        alert.makeAlertTypeCaution()
        alert.cornerRadius = 10
        alert.delegate = self
        alert.animateAlertInFromBottom = true
        alert.animateAlertOutToTop = true
        alert.bounceAnimations = true
        alert.blurBackground = true
        alert.dismissOnOutsideTouch = true
        alert.showAlert(inView: self,
                        withTitle: "Title you want ",
                        withSubtitle: "Subtitle Comes here",
                        withCustomImage: nil,
                        withDoneButtonTitle:"OK" ,
                        andButtons:["Cancel"])
    }

    let edit = UITableViewRowAction(style: .default, title: "Edit")
    {
        (action, index) in
        self.view.makeToast("Editing Coming soon...")

    }

    del.backgroundColor = AppColor.myNewRedColor
    edit.backgroundColor = .lightGray
    return [edit,del]

}

Upvotes: 0

Mahesh Dangar
Mahesh Dangar

Reputation: 804

 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

        let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
            //self.isEditing = false
            print("more button tapped")
        }
        more.backgroundColor = UIColor.lightGray

        let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
            //self.isEditing = false
            print("favorite button tapped")
        }
        favorite.backgroundColor = UIColor.orange

        let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
            //self.isEditing = false
            print("share button tapped")
        }
        share.backgroundColor = UIColor.blue

        return [share, favorite, more]
    }

Upvotes: 1

Jaydeep Vora
Jaydeep Vora

Reputation: 6213

Swift 4.0

You can write below method of tableView to define custom swipe action.

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

       let delete = UITableViewRowAction(style: .default, title: "Delete") { (action, indexPath) in

        }
        delete.backgroundColor = UIColor.red

        let complete = UITableViewRowAction(style: .default, title: "Completed") { (action, indexPath) in
            // Do you complete operation
        }
        complete.backgroundColor = UIColor.blue

        return [delete, complete]
    }

Upvotes: 2

Related Questions