0

I am using Swift 2 and I am stuck in one thing.

I have a TableViewController and I put a UIView in a cell to give a Swipeable effect and also assign custom cell class.

I have a SWRevealViewController.

First I swipe the cell , Second I open the RevealView Sider bar menu. Now when i opne side bar menu cell is not going back to normal.

Can Anyone help me please

Click here! This image show you the swipe effect what i did.

Click here! Now in this image you can clearly see that cell is not closed when i opened the sidebar menu

In my Custom class of SwipeCell , I use the constraints outlets to change the state of UIView.

    *import UIKit
protocol SwipeableCellDelegate: UIGestureRecognizerDelegate
{
    func buttonOneActionForItemText(itemText : Int ,myIndexPath : NSIndexPath)

    func buttonTwoActionForItemText(itemText : Int,myIndexPath : NSIndexPath)

    func buttonThreeActionForItemText(itemText : Int,myIndexPath : NSIndexPath)

}
class SwipeableCellTableViewCell: UITableViewCell {

    @IBOutlet weak var myview: UIView!

    var panRecognizer: UIPanGestureRecognizer!
    var panStartPoint : CGPoint!
    var startingRightLayoutConstraintConstant : CGFloat!

    @IBOutlet weak var contentViewRightConstraint : NSLayoutConstraint!
    @IBOutlet weak var contentViewLeftConstraint : NSLayoutConstraint!


    var halfOfButtonOne: CGFloat!

    @IBOutlet weak var deleteButton: UIButton!

    @IBOutlet weak var seeButton: UIButton!

    @IBOutlet weak var confirmButton: UIButton!

    var delegate: SwipeableCellDelegate?
    var itemText : Int?

    let kBounceValue: CGFloat = 20.0
    var myIndexPath : NSIndexPath!



    override func awakeFromNib() {
        super.awakeFromNib()
        self.panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panThisCell))
        self.panRecognizer.delegate = self
        self.myview.addGestureRecognizer(self.panRecognizer)



    }




    func panThisCell(recognizer: UIPanGestureRecognizer) {
        switch recognizer.state {
        case .Began:
            self.panStartPoint = recognizer.translationInView(self.myview)
            self.startingRightLayoutConstraintConstant = self.contentViewRightConstraint.constant
            print("Pan Began at \(NSStringFromCGPoint(self.panStartPoint))")

        case .Changed:
            let currentPoint = recognizer.translationInView(self.myview)
            let deltaX: CGFloat = currentPoint.x - self.panStartPoint.x
            var panningLeft = false
            if currentPoint.x < self.panStartPoint.x {
                //1
                panningLeft = true
            }
            if self.startingRightLayoutConstraintConstant == 0
            {
                //2
                //The cell was closed and is now opening
                if !panningLeft {
                    let constant: CGFloat = max(-deltaX, 0)
                    //3
                    if constant == 0 {
                        //4
                        self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: false)
                    }
                    else {
                        //5
                        print("changed5: \(constant)")
                        self.contentViewRightConstraint.constant = constant
                    }
                }
                else {
                    let constant: CGFloat = min(-deltaX, self.buttonTotalWidth())
                    //6
                    if constant == self.buttonTotalWidth() {
                        //7
                        self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: false)
                    }
                    else {
                        //8
                        print("changed8: \(constant)")

                        self.contentViewRightConstraint.constant = constant
                    }
                }
            }
            else
            {
                //The cell was at least partially open.
                var adjustment: CGFloat = self.startingRightLayoutConstraintConstant - deltaX
                //1
                if !panningLeft {
                    var constant: CGFloat = max(adjustment, 0)
                    //2
                    if constant == 0 {
                        //3
                        self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: false)
                    }
                    else {
                        //4
                        print("changed4: \(constant)")
                        self.contentViewRightConstraint.constant = constant
                    }
                }
                else {
                    var constant: CGFloat = min(adjustment, self.buttonTotalWidth())
                    //5
                    if constant == self.buttonTotalWidth() {
                        //6
                        self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: false)
                    }
                    else {
                        //7
                        print("changed7: \(constant)")
                        self.contentViewRightConstraint.constant = constant
                    }
                }
            }
            self.contentViewLeftConstraint.constant = -self.contentViewRightConstraint.constant
            //8

        case .Ended:

            if self.startingRightLayoutConstraintConstant == 0 {
                //1
                //Cell was opening
                 halfOfButtonOne = CGRectGetWidth(self.deleteButton.frame) / 2
                //2
                if self.contentViewRightConstraint.constant >= halfOfButtonOne {
                    //3
                    //Open all the way
                    self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: true)
                }
                else {
                    //Re-close
                    self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: true)
                }
            }
            else if startingRightLayoutConstraintConstant <= halfOfButtonOne
            {
                //Cell was closing
                var buttonOnePlusHalfOfButton2: CGFloat = CGRectGetWidth(self.deleteButton.frame) + (CGRectGetWidth(self.seeButton.frame) / 2)
                //4
                if self.contentViewRightConstraint.constant >= buttonOnePlusHalfOfButton2 {
                    //5
                    //Re-open all the way
                    self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: true)
                }
                else {
                    //Close
                    self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: true)
                }
            }
            else
            {
                //Cell was closing
                var buttonOnePlusHalfOfButton3: CGFloat = CGRectGetWidth(self.deleteButton.frame) + CGRectGetWidth(self.seeButton.frame) + (CGRectGetWidth(self.confirmButton.frame)/2)
                //4
                if self.contentViewRightConstraint.constant >= buttonOnePlusHalfOfButton3 {
                    //5
                    //Re-open all the way
                    self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: true)
                }
                else {
                    //Close
                    self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: true)
                }
            }

            print("Pan Ended")

        case .Cancelled:

            if self.startingRightLayoutConstraintConstant == 0 {
                //Cell was closed - reset everything to 0
                self.resetConstraintContstantsToZero(true, notifyDelegateDidClose: true)
            }
            else {
                //Cell was open - reset to the open state
                self.setConstraintsToShowAllButtons(true, notifyDelegateDidOpen: true)
            }

            print("Pan Cancelled")

        default:
            break
        }

    }


    func updateConstraintsIfNeeded(animated: Bool, completion: (finished: Bool) -> Void) {
        var duration: Float = 0
        if animated {
            duration = 0.1
        }
        UIView.animateWithDuration(Double(duration), delay: 0, options: .CurveEaseOut, animations: {() -> Void in
            self.layoutIfNeeded()
            }, completion: completion)
    }


    //Set COnstraint
    func setConstraintsToShowAllButtons(animated: Bool, notifyDelegateDidOpen notifyDelegate: Bool)
    {
        //TODO: Notify delegate.
        if notifyDelegate {
           // self.delegate!.cellDidOpen(self)
        }



        //1
        if self.startingRightLayoutConstraintConstant == self.buttonTotalWidth() && self.contentViewRightConstraint.constant == self.buttonTotalWidth() {
            return
        }
        //2
        self.contentViewLeftConstraint.constant = -self.buttonTotalWidth() - kBounceValue
        self.contentViewRightConstraint.constant = self.buttonTotalWidth() + kBounceValue
        self.updateConstraintsIfNeeded(animated, completion: {(finished: Bool) -> Void in
            //3
            self.contentViewLeftConstraint.constant = -self.buttonTotalWidth()
            self.contentViewRightConstraint.constant = self.buttonTotalWidth() //check1
            self.updateConstraintsIfNeeded(animated, completion: {(finished: Bool) -> Void in
                //4
                self.startingRightLayoutConstraintConstant = self.contentViewRightConstraint.constant
            })
        })
    }


    //Reset Constraints
    func resetConstraintContstantsToZero(animated: Bool, notifyDelegateDidClose notifyDelegate: Bool)
    {

        if notifyDelegate {
            //self.delegate!.cellDidClose(self)
        }

        //TODO: Notify delegate.
//        if self.startingRightLayoutConstraintConstant == 0 && self.contentViewRightConstraint.constant == 0 {
//            //Already all the way closed, no bounce necessary
//            return
//        }

        self.contentViewRightConstraint.constant = -kBounceValue
        self.contentViewLeftConstraint.constant = kBounceValue
        self.updateConstraintsIfNeeded(animated, completion: {(finished: Bool) -> Void in
            self.contentViewRightConstraint.constant = 0
            self.contentViewLeftConstraint.constant = 0
            self.updateConstraintsIfNeeded(animated, completion: {(finished: Bool) -> Void in
                self.startingRightLayoutConstraintConstant = self.contentViewRightConstraint.constant
            })
        })
    }




    func buttonTotalWidth() -> CGFloat {
        return CGRectGetWidth(self.frame) - CGRectGetMinX(self.confirmButton.frame)
    }
    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }


    @IBAction func buttonClicked(sender: AnyObject)
    {
        if sender as! NSObject == self.deleteButton {
            self.delegate?.buttonOneActionForItemText(itemText! ,myIndexPath: myIndexPath)
            print("Clicked delete 1!")
        }
        else if sender as! NSObject == self.seeButton {
            self.delegate!.buttonTwoActionForItemText(itemText!,myIndexPath: myIndexPath)
            print("Clicked see 2!")
        }
        else {
            self.delegate!.buttonThreeActionForItemText(itemText!,myIndexPath: myIndexPath)
            print("Clicked confirm button!")
        }

    }

}

TableViewCellForRow:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SwipeableCellTableViewCell

        let temp = requestedUserInfo[indexPath.row]

        var username = cell.viewWithTag(100) as! UILabel
        var profile = cell.viewWithTag(101) as! UIImageView

        let url = temp.imageUrl[0]

        //print("uname: \(temp.uName)")

        username.text = temp.uName
        profile.kf_setImageWithURL(NSURL(string: url))


        cell.myIndexPath = indexPath
        cell.itemText = indexPath.row
        cell.delegate = self


        //        if self.cellsCurrentlyEditing.contains(indexPath) {
        //            cell.openCell()
        //        }


        return cell
    }

This is viewdidLoad Code:

override func viewDidLoad() {
        super.viewDidLoad()

        navigationController?.navigationBar.translucent = false

        if revealViewController() != nil {
            //revealViewController().rearViewRevealWidth = 62
            sidebarButton.target = revealViewController()
            sidebarButton.action = #selector(SWRevealViewController.revealToggle(_:))

            revealViewController().rightViewRevealWidth = self.view.frame.width-64
            rightReveal.target = revealViewController()
            rightReveal.action = #selector(SWRevealViewController.rightRevealToggle(_:))

            view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
            self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())


        }

        self.refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
        self.refreshControl?.addTarget(self, action: #selector(FriendRequestTableViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)

        if NSUserDefaults.standardUserDefaults().valueForKey(KEY_UID) != nil {
            self.showRequests()
        }
    }
Saad Ullah
  • 103
  • 2
  • 13
  • Reload the data in table view after u did your action using "tableView.reloadData(). Can you please show me your code and UI where issue occurs? – Karthick Selvaraj Nov 11 '16 at 08:16
  • You can see the UI in link. I tried the tableView.reload data but data is updating but cell is in the same state( if cell swiped left then after reloading it will remain in the same state) – Saad Ullah Nov 11 '16 at 08:17
  • Can you show us your cellForRowAtIndexPath() and also how did you make the swipe effect? Chances are that you are not resetting the state of your custom cell when you are dequeuing it. – Chan Jing Hong Nov 11 '16 at 08:24

1 Answers1

0

Well it looks like you're not resetting the constraints when the tableview is reloaded. You can doing something like this in your cellForRowAtIndexPath()

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SwipeableCellTableViewCell

    ...

    cell.myIndexPath = indexPath
    cell.itemText = indexPath.row
    cell.delegate = self
    cell.resetConstraintContstantsToZero(true, notifyDelegateDidClose: false)
    return cell
}

You might want to check if your cell is already closed in your resetConstraintContstantsToZero() function before animating.

By the way, you might want to check this out: Swipe-able Table View Cell in iOS 9

Community
  • 1
  • 1
Chan Jing Hong
  • 2,251
  • 4
  • 22
  • 41
  • Sir can you please help me that how should i check if close or not in resetConstraintConstantsToZero() function. ? – Saad Ullah Nov 11 '16 at 11:19
  • cell.resetConstraintContstantsToZero(true, notifyDelegateDidClose: false) this works :) – Saad Ullah Nov 11 '16 at 12:09
  • @SaadUllah Glad I could help. You can simply use an if else statement to check if the constraints are already 0, and if it already is you don't have to reset the constraints anymore. – Chan Jing Hong Nov 11 '16 at 15:16
  • Thanks ..... Sir can you tell me that how I i refresh when i click the SWRevealController button which opens up side bar menu. – Saad Ullah Nov 12 '16 at 07:32