Salihcyilmaz
Salihcyilmaz

Reputation: 326

Event handling in tableView

What I'm trying to do is handling touch events so that when i screen is getting touched, i want to take some action. For example changing background color The things i tried: // I subclassed table view controller

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
     tableView.backgroundColor = UIColor.orangeColor()
}

that didn't work, i suspected that tvc may not be first responder so that table view handles the touch events. So i tried:

 override func viewDidLoad() {
     super.viewDidLoad()
     tableView.resignFirstResponder()    
}

Also tried:

override func becomeFirstResponder() -> Bool {
    return true
}

override func canBecomeFirstResponder() -> Bool {
    return true
}

None of them work. How can i handle events ? What I'm missing?

EDIT

The selected answer in terms of native swift code:

override func viewDidLoad() {
        super.viewDidLoad()

        var tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tap:")
        tapGestureRecognizer.cancelsTouchesInView = true
        self.tableView.addGestureRecognizer(tapGestureRecognizer)




    }

    func tap(recognizer: UITapGestureRecognizer) {
        if recognizer.state == UIGestureRecognizerState.Ended {
            var tapLocation  = recognizer.locationInView(self.tableView)
            var tapIndexPath : NSIndexPath? = self.tableView.indexPathForRowAtPoint(tapLocation)

            if let index = tapIndexPath  {

                self.tableView(self.tableView, didSelectRowAtIndexPath: index)
            } else {
                self.tableView.backgroundColor = UIColor.orangeColor()
            }
        }

    }

Upvotes: 2

Views: 741

Answers (2)

Allan Chau
Allan Chau

Reputation: 703

Ok, not sure if this is what you are looking for but I think you would still be better off handling the tableView actions though the built in methods. Use custom UITableViewCells and determine what to do depending on the subclass of the cell.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var selectedCell = tableView.cellForRowAtIndexPath(indexPath)

    if let addTableViewCell = selectedCell as? AddNewTableViewCell {
        insertNewObject(addTableViewCell)
    } else if let someOtherTableViewCell = selectedCell as? SomeOtherTableViewCell {
        // Do something else
    }
}

// Copied from the Xcode template
func insertNewObject(sender: AnyObject) {
    objects.insert(NSDate(), atIndex: 0)
    let indexPath = NSIndexPath(forRow: 0, inSection: 0)
    self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}

Upvotes: 0

Pauls
Pauls

Reputation: 2636

If you want to react to touches all over the view, not just the cells, add a tap gesture recognizer in viewDidLoad:

- (void)addTapGestureForListTable {
    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTappedOnView:)];
    tapGestureRecognizer.cancelsTouchesInView = YES;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];
}

And then implement the method userTappedOnView. If you want to distinguish between touches on cells or not, implement it like so:

- (void)userTappedOnView:(UITapGestureRecognizer *)recognizer {
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        CGPoint tapLocation = [recognizer locationInView:self.tableView];
        NSIndexPath *tapIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation];
        if (tapIndexPath) {
            [self tableView:self.tableView didSelectRowAtIndexPath:tapIndexPath];
        }
    }
}

If you want to react to touches on a cell, you have to make your tableView's delegate point to the controller. In viewDidLoad do:

self.tableView.delegate = self;

And then implement the method

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

Upvotes: 5

Related Questions