简体   繁体   中英

Swift - How to hide button in custom tableViewCell class if left “Swipe to delete” detected?

I have a custom cell class with 2 labels displaying a word and its translation. When the user taps one of the labels, I want to open a new view controller with only the label content displayed. We need to understand which label was tapped.

I could not managed to make it work using tapGestureRecognizer and tag on labels because the labels were managed by the class file. I found it easier to add transparent buttons on top of labels.

The segue to the new view controller works fine. But I cannot use anymore the "swipe to delete" on tableViewCells .

When we do the left swipe, the row is moving left, it displays the red squared "DELETE" button on the right side of the row, but at the same time it performs the segue to the new viewController.

How can I hide / deactivate buttons in tableViewCell if left "Swipe to delete" is detected?

I tried to add a left swipeGestureRecognizer and add a common variable isSwipingLeft: Bool to different places ( viewDidEndEditing ...etc) without success. The best I did was to detect the swipe, hide the button, but could not unhide the button back...

EDIT:

DetailListCell

protocol CustomCellDelegate {
func leftButtonTapped(cell: DetailListCell)
func rightButtonTapped(cell: DetailListCell)
}

class DetailListCell: UITableViewCell {

@IBOutlet weak var entryLeftLbl: UILabel!
@IBOutlet weak var entryRightLbl: UILabel!
@IBOutlet weak var leftButtonOutlet: UIButton!
@IBOutlet weak var rightButtonOutlet: UIButton!
var delegate: CustomCellDelegate?

func configureDetailListCell(entry: Entry) {
entryLeftLbl.isUserInteractionEnabled = true
entryRightLbl.isUserInteractionEnabled = true
// cell configuration to hide/display labels and buttons ...
}

@IBAction func leftButton(_ sender: Any) {
if isSwipingToDelete == false {
delegate?.leftButtonTapped(cell: self)
}}   

@IBAction func rightButton(_ sender: Any) {
if isSwipingToDelete == false {
delegate?.rightButtonTapped(cell: self)
}}}

DetailListVC

override func viewDidLoad() {
detailTableView.delegate = self
detailTableView.dataSource = self        

// Swipe left
let swipeLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(DetailListVC.swipeLeft(gestureRecognizer:)))
swipeLeft.direction = .left
self.view!.addGestureRecognizer(swipeLeft)
}

// Swipe left to detect Swipe to delete
func swipeLeft(gestureRecognizer: UISwipeGestureRecognizer) {
isSwipingToDelete = true
}

func leftButtonTapped(cell: DetailListCell) {
// Find the row of the textField
let indexPath = self.detailTableView.indexPathForRow(at: cell.center)!        
// Find the Entry object of the row/textField selected
if let objs = controller.fetchedObjects , objs.count > 0 {
let item = objs[indexPath.row].faceA
performSegue(withIdentifier: "FullEntryVC", sender: item)
}}

func rightButtonTapped(cell: DetailListCell) {        
// Find the row of the textField
let indexPath = self.detailTableView.indexPathForRow(at: cell.center)!        
// Find the Entry object of the row/textField selected
if let objs = controller.fetchedObjects , objs.count > 0 {
let item = objs[indexPath.row].faceB
performSegue(withIdentifier: "FullEntryVC", sender: item)
}}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FullEntryVC" {
if let destination = segue.destination as? FullEntryVC {
if let entryFace = sender as? String {
isEditMode = false
destination.entryLabelValue = entryFace
}}}}

As Valdmer proposed I used isEditing property of UITableViewCell . I added a if statement inside the methods of my buttons to check if cell.isEditing == false . If false then performSegue(withIdentifier: ) is run, if true then the "swipe to delete" is working fine and the button does nothing.

I removed all piece of code relative to NSNotification and to swipeLeft(gestureRecognizer: ) .

Here is the updated code for one of the button:

func leftButtonTapped(cell: DetailListCell) {
    // Check if "swipe to delete" is detected:
    if cell.isEditing == false {

        // Find the row of the textField
        let indexPath = self.detailTableView.indexPathForRow(at: cell.center)!

        // Find the Entry object of the row/textField selected
        if let objs = controller.fetchedObjects , objs.count > 0 {
            let item = objs[indexPath.row].faceA
            performSegue(withIdentifier: "FullEntryVC", sender: item)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM