user2545883
user2545883

Reputation: 131

How can I receive touches using tvOS?

How can I receive touches using tvOS with the simulator? We need know touch position. UIPress - have no it!

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    // Never called
}

-(void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event {
    // Works fine!
}

Upvotes: 10

Views: 8263

Answers (4)

fredericdnd
fredericdnd

Reputation: 1008

An easy way to do that :

var tapGestureRecognizer: UITapGestureRecognizer!

override func didMoveToView(view: SKView) {

    tapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: Selector("tapped:"))
    self.view?.addGestureRecognizer(tapGestureRecognizer)

}

func tapped(sender: UITapGestureRecognizer) {

    // do something

}

Take a look to my repository : https://github.com/fredericdnddev/tvOS-UITapGestureRecognizer/blob/master/tvOS%20Game/GameScene.swift

Upvotes: 0

lemnar
lemnar

Reputation: 4053

Presses are related to physical buttons, like the Menu button. A press begins when you start holding down such a button, and it ends when you stop holding down the button. There isn't any screen-relative position associated with a press.

Touches in tvOS are similar to touches in iOS, but there's one important difference: they're "indirect" touches, i.e. there isn't a physical relationship between the location of the finger and a location on screen.

When a touches begins, it will be delivered to the focused view, and the touch will be considered to have started in the center of that view, regardless of the absolute position of the finger on the touch surface. As the touch moves, its screen-relative position will be updated accordingly.

I'm not aware of any API that would allow you to determine the absolute position of a finger on the touch surface.

In your case, making your responder the focused view should cause it to receive touch events.

Upvotes: 12

Spentak
Spentak

Reputation: 3359

Keep in mind tvOS doesn't have the notion of "touching" as in touching the screen.

The official way to handle "taps" is using UITapGestureRecognizer. And that would be when the user taps/clicks the remote when an item is in a focus state.

Here is how I am doing it working with a UICollectionView:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    if let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MovieCell", forIndexPath: indexPath) as? MovieCell {

        let movie = movies[indexPath.row]
        cell.configureCell(movie)

        if cell.gestureRecognizers?.count == nil {
            let tap = UITapGestureRecognizer(target: self, action: "tapped:")
            tap.allowedPressTypes = [NSNumber(integer: UIPressType.Select.rawValue)]
            cell.addGestureRecognizer(tap)
        }

        return cell

    } else {
        return MovieCell()
    }
}

func tapped(gesture: UITapGestureRecognizer) {

    if let cell = gesture.view as? MovieCell {
        //Load the next view controller and pass in the movie
        print("Tap detected...")
    }
}

You can grab the position of the tap from the UITapGestureRecognizer that gets passed in on the handler function.

Also see this tutorial on Apple TV: https://www.youtube.com/watch?v=XmLdEcq-QNI

Upvotes: 0

Mattias Lindberg
Mattias Lindberg

Reputation: 2116

I think it should be pressesBegan instead of touchedBegan.

(void)pressesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event

Upvotes: 3

Related Questions