I am adding a UITapGesture to some views. It is working fine only in iPhone 7 plus. The gesture method does not get called for other devices(iPhone 8, 6, 5s). Has anyone faced this kind of issue? I am just curious why is this happening? Has this something to do with Autolayout?
let tabGesture = UITapGestureRecognizer(target: self, action: #selector(handlePassTap(_:)))
tabGesture.numberOfTapsRequired = 1
self.passTabContainer.addGestureRecognizer(tabGesture)
let textGesture = UITapGestureRecognizer(target: self, action: #selector(handlePassTap(_:)))
textGesture.numberOfTapsRequired = 1
self.passTextContainer.addGestureRecognizer(textGesture)
#objc func handlePassTap(_ gesture:UITapGestureRecognizer)
{
performSegue(withIdentifier: "passSegue", sender: currentPass)
}
Yes. There was a view on top of those gesture views that was blocking the tap. Resolved it now.
Related
I'm working on a small SpriteKit game for tvOS. I need to receive input when the user clicks the play/pause button on the remote. Looking at the docs, it appears that I should just have to add a UITapGestureRecognizer to my scene's view. I implemented the following code:
override func didMove(to view: SKView) {
let tapPlayPause = UITapGestureRecognizer(target: self, action: #selector(tapTesting))
tapPlayPause.allowedPressTypes = [NSNumber(value: UIPress.PressType.playPause.rawValue)]
view.addGestureRecognizer(tapPlayPause)
let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(swipeUp))
swipeUp.direction = .up
view.addGestureRecognizer(swipeUp)
}
#objc func tapTesting(_ sender: UITapGestureRecognizer) {
print("TAP")
}
However, when I run the app on my Apple TV 4K (running tvOS 15), there is no output and from what I can tell no tap code is getting triggered.
I have tried the code with self.isUserInteractionEnabled = true as well but I still do not receive tap inputs.
The swipe gesture I implemented above works perfectly thought, and the tap gesture works on my iOS devices. Does anyone have any idea as to why this is the case?
Thanks!
For tvOS gestures, you also need to set allowedTouchTypes to .indirect
tapPlayPause.allowedTouchTypes = [NSNumber(touchType: .indirect)]
I've added a label in a view controller via the interface builder, and I've added a lot of constraints to it, but I want to replace it by a button. Can I accomplish this without losing all the constraints ? Thanks a lot in advance
I'm not sure if you can save your constraints inside interface builder. However, you can add a tap gesture recognizer to make the label perform an action when it is tapped (act like a button).
This code can help you get started:
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_ :)))
myLabel.isUserInteractionEnabled = true
myLabel.addGestureRecognizer(tapGestureRecognizer)
func handleTap(_ sender: UITapGestureRecognizer) {
// perform some action when the label is tapped
}
You can look at this question for more information.
Don’t replace by button
Add tap gesture for click action
you don't need to remove that label. Just addGestureRecognizer a tap gesture on label.
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(_ :)))
myLabel.isUserInteractionEnabled = true
myLabel.addGestureRecognizer(tapGestureRecognizer)
func handleTap(_ sender: UITapGestureRecognizer) {
// perform some action when the label is tapped
}
In my tvOS app I have a collection view with cells that represent movies.
I attached 2 gesture recognizers to the view:
Go to movie details on selection tap
Play movie directly (with an Apple TV Remote dedicated Play button)
let posterTap = UITapGestureRecognizer(target: self, action: #selector(ListViewController.movieSelect(_:)))
posterTap.allowedPressTypes = [NSNumber(integer: UIPressType.Select.rawValue)]
self.view.addGestureRecognizer(posterTap)
let posterPlay = UITapGestureRecognizer(target: self, action: #selector(ListViewController.moviePlay(_:)))
posterPlay.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)]
self.view.addGestureRecognizer(posterPlay)
And the respected methods
func movieSelect(gesture: UITapGestureRecognizer) {
if let cell = UIScreen.mainScreen().focusedView as? ItemCollectionViewCell {
let item = ItemViewController(nibName: "ItemViewController", bundle: nil)
item.item = cell.data
self.presentViewController(item, animated: true, completion: nil)
}
}
func moviePlay(gesture: UITapGestureRecognizer) {
if let cell = UIScreen.mainScreen().focusedView as? ItemCollectionViewCell {
let data = cell.data
// TLDR;
// Passing data to AVPlayerViewController and presenting it + start playing the movie.
}
}
Everything seem to work, apart from the fact that when I stop playing the movie and coming back to the list (by closing the AVPlayerViewController), my second gesture recognizer (Play button) no longer works. It is still there if I check with print(self.view.gestureRecognizers) but moviePlay() is never called again no matter what.
Is there a way to debug this? What may cause this issue? I'm thinking this is caused by UIGestureRecognizerState being still in "use"? Or maybe something like that. At this point I have no clue.
I've experience weirdness with gesture recognizers on tvOS. In my case, for some reason, the app behaved as if gesture recognizers were lingering on after container view had been dismissed. Oddly enough, I've observed this weirdness when launching and closing AVPlayerViewController a few times as well.
What I did to fix this was to remove use of gesture recognizers and overriding pressesEnded method instead.
I hope this helps.
I'm building a iOS Swift (Sprite kit) game. I'm using swipes to move the player. While testing I've found out that everything works just fine on most devices. However, a few devices do not recognise the swipe. Needless to say, the game doesn't work without the swipes. It's very odd that it works on almost all devices but a few.
My code is below. (Note: It's cleaned up to show only the code relevant for this case)
Edit
The app is currently being tested on actual devices. All devices run the latest iOS software. Mostly iPhone 5, a few 6 and 5S. Error occurs on iPhone 5S.
Am I missing something? If not, what else could I try?
override func didMoveToView(view: SKView) {
addSwipes()
}
func addSwipes() {
let swipeRight:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedRight:"))
swipeRight.direction = .Right
view!.addGestureRecognizer(swipeRight)
let swipeLeft:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedLeft:"))
swipeLeft.direction = .Left
view!.addGestureRecognizer(swipeLeft)
}
func swipedRight(sender:UISwipeGestureRecognizer) {
// Do code here
}
func swipedLeft(sender:UISwipeGestureRecognizer) {
// Do code here
}
Exactly what the title implies. How do the gesture recognizers work, specifically UIGestureRecognizer. Here is a small snippet of my code
var keyboardDismiser: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "gestureRecognizer:")
keyboardDismiser.direction = .Right | .Left
noteView.addGestureRecognizer(keyboardDismiser)
and
func gestureRecognizer(sender: UISwipeGestureRecognizer!) {
println("swipe")
self.view.endEditing()
}
My goal is to dismiss the keyboard when switching from view to view in a UIScrollView with 3 pages. What am I doing wrong? There isn't much documentation on this in Swift.
First you setting the recognizer on the note view. It will only be active on the note view.
In addition, you are not setting direction correctly. You are setting then changing the it's value. To set it to both right and left, you use the | operator. Also direction knows it a UISwipeGestureRecognizerDirection so you don't need specify that.
var keyboardDismiser = UISwipeGestureRecognizer(target: self, action: "gestureRecognizer:")
keyboardDismiser.direction = .Right | .Left
self.view.addGestureRecognizer(keyboardDismiser)
Finally, I would use endEditing() instead of resignFirstResponder().
func gestureRecognizer(sender: UISwipeGestureRecognizer!) {
println("swipe")
self.view.endEditing(true)
}
Hope that helps.
I believe that selectors in Swift do not need the : at the end; they're just a string with the name of the function: gestureRecognizer. So this is what you should have:
var keyboardDismiser = UISwipeGestureRecognizer(target: self, action: "gestureRecognizer")
Relevant question here.