10

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!
}
user2545883
  • 131
  • 1
  • 5

4 Answers4

12

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.

lemnar
  • 4,063
  • 1
  • 32
  • 44
  • https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/DetectingButtonPressesandGestures.html#//apple_ref/doc/uid/TP40015241-CH16-SW1 – Mark Sep 15 '15 at 12:43
  • Actually you can get absolute values by setting GCMicroGamepad's reportsAbsoluteDpadValues to YES. Please see this: https://developer.apple.com/library/tvos/documentation/GameController/Reference/GCMicroGamepad_Ref/index.html#//apple_ref/occ/instp/GCMicroGamepad/reportsAbsoluteDpadValues – Elviss Strazdins Dec 06 '15 at 04:25
  • This is for the game controller, not for the remote as I understand. – Eugene Gordin Jan 20 '16 at 00:16
  • 1
    The remote is a game controller. It implements the [`GCMicroGamepad`](https://developer.apple.com/library/prerelease/tvos/documentation/GameController/Reference/GCMicroGamepad_Ref/index.html#//apple_ref/occ/cl/GCMicroGamepad) profile. – rob mayoff Feb 11 '16 at 16:19
  • However, when you use the remote as a game controller, it doesn't work with UIKit. You can get high-level / indirect / navigation-style input (`UIPress`, `UITouch`, `UIGestureRecognizer`, etc), ***or*** you can get absolute / direct input (`GCMicroGamepad`), but not both at the same time. See [Working With Game Controllers](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/WorkingwithGameControllers.html#//apple_ref/doc/uid/TP40015241-CH18-SW1) in *App Programming Guide for tvOS*. – rickster Feb 11 '16 at 19:20
  • So will making the responder the focused view allow touchesBegan to be triggered? How do I make the responder the focused view? – user1615898 Feb 12 '16 at 17:14
3

I think it should be pressesBegan instead of touchedBegan.

(void)pressesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
Mattias Lindberg
  • 2,064
  • 3
  • 24
  • 34
  • you right! presses Began, Cansel, Ended - All work fine. We need a Touch type - with Position by X and Y on touch panel! – user2545883 Sep 11 '15 at 17:52
  • @user2545883 please mark this as the correct answer if it solved your issue so others with the same issue will know this is the solution – Chris Sep 11 '15 at 18:27
0

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

Spentak
  • 3,359
  • 3
  • 21
  • 31
  • You shouldn't need a tap gesture recognizer in this case. The normal UICollectionView didSelect... delegate methods should work just like on iOS. – lemnar Sep 13 '15 at 07:51
  • lemnar - they don't. Spent quite a few hours trying to get that to work until i read the docs. The focus state and then controller tap has no context of indexPath, so you have to use the tap gesture. – Spentak Sep 13 '15 at 15:01
  • How do you differentiate taps from clicks? – David Oct 19 '15 at 18:34
0

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

fredericdnd
  • 968
  • 1
  • 14
  • 25
  • Question is marked objective c, and that's what user2545883 is looking for. Posting swift solution is not helpful for him, nor others like myself looking for objective c examples. – seaders Nov 16 '15 at 22:26
  • 1
    the problem with this solution is that this is PRESS not TAP. The question was to get the coordinates of the TAP! Press doesn't have the coordinates. One of the ways to get the coordinates from touches in TVOS is to use UIPanGestureRecognizer. – Eugene Gordin Jan 20 '16 at 00:10