Saturday 16 April 2016

Custom Swipe Table View Cell

In our most of the apps we generally see that we have some options that we can perform  while swiping the cell. Default swipe actions provided by iOS can only show the text and don’t have customization options. Today you will lean how we can add our custom swipe actions in a UITableview cell.

But before moving that we need PKSwipeTableViewCell file that I have created to provide custom swipe action. You can download the file from the below github sample project.

Now create a single view application and add a UITableView in view controller. Create a custom class for the cell and  inherit it from the PKSwipeTableViewCell. 

In our demo we will add a call button while swiping the cell, so create a function and add the code to display the call option.

func addRightViewInCell() {
       
        //Create a view that will display when user swipe the cell in right
        let viewCall = UIView()
        viewCall.backgroundColor = UIColor.lightGrayColor()
        viewCall.frame = CGRectMake(0, 0,CGRectGetHeight(self.frame)+20,CGRectGetHeight(self.frame))

        //Add a label to display the call text
        let lblCall = UILabel()
        lblCall.text  = "Call"
        lblCall.font = UIFont.systemFontOfSize(15.0)
        lblCall.textColor = UIColor.yellowColor()
        lblCall.textAlignment = NSTextAlignment.Center
        lblCall.frame = CGRectMake(0,CGRectGetHeight(self.frame) - 20,viewCall.frame.size.width,20)

        //Add a button to perform the action when user will tap on call and add a image to display
        let btnCall = UIButton(type: UIButtonType.Custom)
        btnCall.frame = CGRectMake((viewCall.frame.size.width - 40)/2,5,40,40)
        btnCall.setImage(UIImage(named: "call"), forState: UIControlState.Normal)
        btnCall.addTarget(self, action: "callButtonClicked", forControlEvents: UIControlEvents.TouchUpInside)

        viewCall.addSubview(btnCall)
        viewCall.addSubview(lblCall)
        //Call the super addRightOptions to set the view that will display while swiping
        super.addRightOptionsView(viewCall)
    }

Here you can see that we are calling super class function addRightOptions, this gives you the flexibility to show any view that you want to create. You can create multiple views(like call,message) and display them here.

When the user will swipe the cell and tap on any option then we have to again bring the cell in normal state. For that we have to call reset function.

func callButtonClicked(){
      //Reset the cell state and close the swipe action
        self.resetCellState()
}

It’s depends on the requirement that we have to make the cell again in normal state or not. If you want to remain open then there is no need to call the reset function.

Swipe cell class also provide the delegate methods when the swipe action begins on the cell. We may require in some case to reset the swipe cell when user tries to perform the swipe action on other cell. To achieve this you have to store the old cell on which swipe was performed and return that cell in the swipe delegate.

// PKSwipeTableViewCell Delegate
    func swipeBeginInCell(cell: PKSwipeTableViewCell) {
        oldStoredCell = cell
    }
   
    func swipeDoneOnPreviousCell() -> PKSwipeTableViewCell? {
        guard let cell = oldStoredCell else {
            return nil
        }
        return cell
    }

Note: - Don’t forgot to set the cell delegate to point your view controller otherwise methods will not get called.

That’s all we have successfully integrated it.
Here is sampleproject with all the code of the above tutorial.

If you face any issue or have any suggestions,please leave your comment.



25 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. How do you add more than one button ? I've tried exploring and have tried to just add another UIView to pass to: super.addRightOptionsView(actionAddToBox)
    but that didn't work.

    ReplyDelete
    Replies
    1. It will not work if you call the addRightOptionsView twice. You have to create only one view and inside that view add two buttons and pass that view to addRightOptionView. This will display the two buttons.

      Let me know if you face any issue. I will be happy to help you.

      Delete
  4. Is this code available in Objective-C?

    ReplyDelete
  5. how to get index Path when i click call option

    ReplyDelete
    Replies
    1. Please guide me solution. My case is i have to do delete functionality. So I need indexpath here

      Delete
    2. If you have created a custom class of cell then you can pass the delegate of your viewcontroller in cell class and then from that delegate you can call any method of your view controller, where you can get index path by calling indexPathforcell on table view. Cell object you can pass in perform selector.

      Please let me know if you need more help.

      Delete
  6. That is fine. Could you please tell me How to refresh the swipe.

    My case, I dont want to show for all cell. If it is my own comment cell only have to show delete option. Here after deleting a row and add a new row, keeping the previous position state also


    func configureCell(row:Int, userID: String,msg: String) {
    // self.lblTitle.text = strToSet
    self.userID = userID;
    self.commentCount = row;
    print("row ==== :\(row) =====:\(msg)")
    print(":\(userID) ==loged=:\(Globals.sharedInstance.userId) =====:\(userID == Globals.sharedInstance.userId)")

    if(userID == Globals.sharedInstance.userId){
    self.addRightViewInCell()
    }


    }

    ReplyDelete
    Replies
    1. Explain about my problem clearly;

      I have list of comments. If it is my own comment, when user swipe to left to right , delete option will be enable.After deleting the comments , it will reload the table. User can add new comment in the same page, that time also, it will reload the table.

      Problem is that;

      When I scroll the comment, it shows the delete option in wrong manner also. I have checked user id with the comment. Please guide me. It was working in the normal way. Now current requirement was to show delete icon.

      Delete
    2. If swipe has already added, how to remove from the cell?

      Delete
    3. So if cell is in open state and you want to close it then make a call to resetCellState().

      If you want some cell have swipe option and some don't have then you have to conditionally add it on cellforrow method. call the addRightView in cellforRow where you want the swipe only. Make sure you are not calling it anywhere else in cell class.

      By this it will swipe only where you have added swipe option.

      Please let me know if you need any more help.

      Delete
  7. Thanksgiving Day 2016 is definitely going to be a memorable day for you and your friends that reunion on a Thanksgiving party because pie recipes are at your hand now. http://www.thanksgivingday-2016.com/

    ReplyDelete
  8. Hi... :)
    Very cool your example...
    I'm a new programer and
    i would like to know how to implement the click of addRightViewInCell to delete
    a current item?
    I am trying to make this, but i've yet do not yet achived.

    In a normal cel with a button excluir i would do this..:

    -*-*-*-*-*-*-*-*-*-*-*-*

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
    {
    let remove = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: " ") { (action: UITableViewRowAction, indexPath: IndexPath) -> Void in

    self.vVoice_Mail_Class.remove(at: indexPath.row);

    tableView.deleteRows(at: [indexPath], with: .top);

    }

    remove.backgroundColor = UIColor(patternImage: UIImage(named: "botao_deletar")!)
    return [remove];
    }

    -*-*-*-*-*-*-*-*-*-*-*-*



    I think the answer to my question has been answered the friend
    Piraba-Nagkeeran10 July 2016 at 08:24 but i did not understand the answer.

    Thank you in advance for your attention.
    Tankyou again :)

    ReplyDelete
    Replies
    1. Hi,

      I am not able to get your question.

      If you want to delete option then you can add the delete image instead of call image provided in the sample app.

      Also, you can add more than one buttons on the swipe cell to implement the different functionality.

      Please let me know your question in more detail so that I can better provide a answer.

      Thanks

      Delete
    2. Hi..
      Firstlly i would like to tanks your atenttion :)

      I want make the buttom (call button) delete a row.

      I don't know implement this code. :)

      thanks.. again :)

      Delete