I have a screen with 6 buttons. All the buttons are connected to one IBAction. They are tagged and I use a switch statement to determine which one was tapped.
How can I add a Long and Tap gesture to each button? So for example when I tap button 1 it know if its a long gesture or a tap gesture?
So if I tap the button will do something different then when I long press.
Thanks.
#IBAction func playPauseAudioButton(sender: UIButton) {
switch sender.tag {
case 1:
//Tap Gesture
//Long Gesture
//I need this for every button
print("1")
case 2:
print("2")
case 3:
print("3")
case 4:
case 5:
print("5")
case 6:
print("6")
default:
print("Default")
}
}
Do it like this
#IBAction func playPauseAudioButton(sender: AnyObject) {
let tapGesture = UITapGestureRecognizer(target: self, action: "normalTap:")
let longGesture = UILongPressGestureRecognizer(target: self, action: "longTap:")
tapGesture.numberOfTapsRequired = 1
sender.addGestureRecognizer(tapGesture)
sender.addGestureRecognizer(longGesture)
}
func normalTap(sender : UIGestureRecognizer) {
let recognizer: UIGestureRecognizer = sender
let tag: Int = recognizer.view!.tag
switch tag {
case 1:
// Do some action for button 1
print("1")
case 2:
print("2")
case 3:
print("3")
case 4:
print("4")
case 5:
print("5")
case 6:
print("6")
default:
print("Default")
}
}
func longTap(sender : UIGestureRecognizer) {
let recognizer: UIGestureRecognizer = sender
let tag: Int = recognizer.view!.tag
if sender.state == .Ended {
print("UIGestureRecognizerStateEnded")
//Do Whatever You want on End of Gesture
}
else if sender.state == .Began {
print("UIGestureRecognizerStateBegan.")
//Do Whatever You want on Began of Gesture
}
switch tag {
case 1:
// Do some action for button 1
print("1")
case 2:
print("2")
case 3:
print("3")
case 4:
print("4")
case 5:
print("5")
case 6:
print("6")
default:
print("Default")
}
}
Define two IBActions and set one Gesture Recognizer to each of them. This way you can perform two different actions for each gesture.
You can set each Gesture Recognizer to different IBActions in the interface builder.
#IBAction func tapped(sender: UITapGestureRecognizer)
{
println("tapped")
//Your animation code.
}
#IBAction func longPressed(sender: UILongPressGestureRecognizer)
{
println("longpressed")
//Different code
}
Through code without interface builder
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapped:")
self.view.addGestureRecognizer(tapGestureRecognizer)
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.view.addGestureRecognizer(longPressRecognizer)
func tapped(sender: UITapGestureRecognizer)
{
println("tapped")
}
func longPressed(sender: UILongPressGestureRecognizer)
{
println("longpressed")
}
Hope this helps you.
Related
I have implemented a switch statement. Now I am struggling to add a double tap gesture to dispaly a more information depnding on the case chosen from the switch.
override func viewDidLoad() {
let tap = UITapGestureRecognizer(target: self, action: #selector(moreInfo))
tap.numberOfTapsRequired = 2
view.addGestureRecognizer(tap)
}
// the main switch case
switch choice {
case 1:
print("1 is chosen")
moreInfo(option:1)
case 2:
print("2 is chosen")
moreInfo(option:2)
}
//to be activated when double tap
#objc func moreInfo(option: Int) {
switch choice {
case 1:
print("more information for 1")
case 2:
print("more information for 2")
}
}
I just write some example code. Hope it help.
Like below code, you can use double and single tap actions.
class ViewController: UIViewController {
var singleTap: UITapGestureRecognizer!
var doubleTap: UITapGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
doubleTap = UITapGestureRecognizer(target: self, action: #selector(tap(gesture:)))
view.addGestureRecognizer(doubleTap)
doubleTap.numberOfTapsRequired = 2
doubleTap.delaysTouchesBegan = true
singleTap = UITapGestureRecognizer(target: self, action: #selector(tap(gesture:)))
singleTap.delaysTouchesBegan = true
singleTap.require(toFail: doubleTap)
view.addGestureRecognizer(singleTap)
}
#objc
func tap(gesture: UITapGestureRecognizer) {
switch gesture {
case singleTap:
moreInfo(option: 1)
case doubleTap:
moreInfo(option: 2)
default:
print("---")
}
}
func moreInfo(option: Int) {
switch option {
case 1:
print("more information for 1")
case 2:
print("more information for 2")
default:
print("---")
}
}
}
I am creating swift application and i am using UISwipegesture i am swiping up and down direction and its work perfectly but when usewr swipe up or down i will hide show view and it hide and show as expected but when swiping stopped i want that view show automatically
let me Show my code for better understanding
Code
videDidLoad()
let swipe = UISwipeGestureRecognizer(target: self, action:
#selector(respondToSwipeGesture(gesture:)))
swipe.direction = UISwipeGestureRecognizer.Direction.up
swipe.delegate = self
self.view.addGestureRecognizer(swipe)
let swipe1 = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture(gesture:)))
swipe1.direction = UISwipeGestureRecognizer.Direction.down
swipe1.delegate = self
self.view.addGestureRecognizer(swipe1)
#objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizer.Direction.up:
print("Swiped up")
viewFilter.isHidden = true
case UISwipeGestureRecognizer.Direction.down:
print("Swiped down")
viewFilter.isHidden = true
default:
break
}
}
}
here you can able to see that on up down direction i hide view but when swipe stop i want that again show that view so i cant under stand how to do that can any please help me
Use the UIGestureRecognizer.State appledoc
In your selector do something like this
#objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizer.Direction.up:
print("Swiped up")
viewFilter.isHidden = true
case UISwipeGestureRecognizer.Direction.down:
print("Swiped down")
viewFilter.isHidden = true
default:
break
}
// code for looking up which state the gesture currently is in.
switch swipeGesture.state {
case .ended, .failed:
viewFilter.isHidden = false
// list up other cases here
}
}
}
You can use state for gesture recognizer:
#objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizer.Direction.up:
print("Swiped up")
viewFilter.isHidden = true
case UISwipeGestureRecognizer.Direction.down:
print("Swiped down")
viewFilter.isHidden = true
default:
break
}
if swipeGesture.state == .ended {
viewFilter.isHidden = false
}
}
}
Get the ended state of UIGestureRecognizer and then show the view. See this doc
#objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
if swipeGesture.state == .ended {
viewFilter.isHidden = false
}
}
}
I have a UIView that I added a UILongPressGestureRecognizer to so that I can handle clicks and have that UIView work like a button.
let longPressGtr = UILongPressGestureRecognizer(target: self, action:#selector(longPressSelector))
longPressGtr.minimumPressDuration = 0.1
myView.isUserInteractionEnabled = true
myView.addGestureRecognizer(longPressGtr)
#objc func longPressSelector(_ gestureRecognizer: UILongPressGestureRecognizer) {
if gestureRecognizer.state == .began {
myView.backgroundColor = UIColor.gray
} else if gestureRecognizer.state == .ended {
myView.backgroundColor = UIColor.blue // my button is blue
doSomething()
}
}
func doSomething() {
print("view was pressed")
}
This works, but the one thing that doesn't is when I press and hold on my UIView but drag my finger off the view, the "button" doesn't unselect. It still fires doSomething(). A regular UIButton will deselect the button and not fire it's onClick if you are holding down on it an drag your finger off the view.
How can I implement this functionality into my UIView?
Or is there a better way to make a UIView act like a button?
You need to check whether the gesture is inside the view.
#objc func longPresserDidFire(_ presser: UILongPressGestureRecognizer) {
let gestureIsInside = myView.point(inside: presser.location(in: myView), with: nil)
switch presser.state {
case .began, .changed:
if gestureIsInside {
myView.backgroundColor = .blue
} else {
myView.backgroundColor = .gray
}
case .cancelled:
myView.backgroundColor = .gray
case .ended:
myView.backgroundColor = .gray
if gestureIsInside {
doSomething()
}
default: break
}
}
You are not adding condition of gestureRecognizer state changed that's why it is accepting the end state.
#objc func longPressSelector(_ gestureRecognizer: UILongPressGestureRecognizer) {
if gestureRecognizer.state == .began {
} else if gestureRecognizer.state == .changed {
}else if gestureRecognizer.state == .ended {
}
}
Add one more condition and check if it works.
When you drag your finger outside of the view, gestureRecognizer is probably translated to failed or cancelled state, so you need to add handling of this cases gestureRecognizer.state == .failed and gestureRecognizer.state == .cancelled.
#objc func longPressSelector(_ gestureRecognizer: UILongPressGestureRecognizer) {
}
Place UILongPressGestureRecognizer instead of UITapGestureRecognizer and check it
I'm having a little trouble with the gestures.
I'm trying to use both tap and long press on the same button, so I've used
#IBAction func xxx (sender: UITapGestureRecognizer)
and
#IBAction func xxx (sender: UILongPressGestureRecognizer)
but my button seems to react to both functions when I tap. What might be wrong?
func long(longpress: UIGestureRecognizer){
if(longpress.state == UIGestureRecognizerState.Ended){
homeScoreBool = !homeScoreBool
}else if(longpress.state == UIGestureRecognizerState.Began){
print("began")
}
}
Hard to say what´s not working with your code, with the only two rows that you have provided, but I would recommend you to do it in this way instead:
Create an outlet to your button instead
#IBOutlet weak var myBtn: UIButton!
And in your viewDidLoad() add the gestures to the buttons
let tapGesture = UITapGestureRecognizer(target: self, action: "normalTap")
let longGesture = UILongPressGestureRecognizer(target: self, action: "longTap:")
tapGesture.numberOfTapsRequired = 1
myBtn.addGestureRecognizer(tapGesture)
myBtn.addGestureRecognizer(longGesture)
And then create the actions to handle the taps
func normalTap(){
print("Normal tap")
}
func longTap(sender : UIGestureRecognizer){
print("Long tap")
if sender.state == .Ended {
print("UIGestureRecognizerStateEnded")
//Do Whatever You want on End of Gesture
}
else if sender.state == .Began {
print("UIGestureRecognizerStateBegan.")
//Do Whatever You want on Began of Gesture
}
}
Swift 3.0 version:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.normalTap))
let longGesture = UILongPressGestureRecognizer(target: self, action: Selector(("longTap:")))
tapGesture.numberOfTapsRequired = 1
myBtn.addGestureRecognizer(tapGesture)
myBtn.addGestureRecognizer(longGesture)
func normalTap(){
print("Normal tap")
}
func longTap(sender : UIGestureRecognizer){
print("Long tap")
if sender.state == .ended {
print("UIGestureRecognizerStateEnded")
//Do Whatever You want on End of Gesture
}
else if sender.state == .began {
print("UIGestureRecognizerStateBegan.")
//Do Whatever You want on Began of Gesture
}
}
Updated syntax for Swift 5.x:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(normalTap))
button.addGestureRecognizer(tapGesture)
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
button.addGestureRecognizer(longGesture)
#objc func normalTap(_ sender: UIGestureRecognizer){
print("Normal tap")
}
#objc func longTap(_ sender: UIGestureRecognizer){
print("Long tap")
if sender.state == .ended {
print("UIGestureRecognizerStateEnded")
//Do Whatever You want on End of Gesture
}
else if sender.state == .began {
print("UIGestureRecognizerStateBegan.")
//Do Whatever You want on Began of Gesture
}
}
i have a project in xcode 7 ( swift ) that i want to load differents viewscontrollers designeds in storyboard with the function swipe right and left and go to next viewcontroller or back.
Now i have this but only fade in right to left and i want the two fade ins.
func respondToSwipeGesture(sender: UISwipeGestureRecognizer) {
switch sender.direction {
case UISwipeGestureRecognizerDirection.Right:
print("SWIPED DERECHA")
self.performSegueWithIdentifier("cambio2", sender: nil)
case UISwipeGestureRecognizerDirection.Left:
print("SWIPED IZQUIERDA")
self.performSegueWithIdentifier("cambio", sender: nil)
default:
break
}
}
You can also use UISwipeGestureRecognizer by creating 2 instance of it.
one for each direction.
var swipeLeft : UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "swipe:")
swipeLeft.direction = UISwipeGestureRecognizerDirection.Left
var swipeRight : UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "swipe:")
swipeRight.direction = UISwipeGestureRecognizerDirection.Right
self.view.addGestureRecognizer(swipeLeft)
self.view.addGestureRecognizer(swipeRight)
and the swipe function
func swipe(sender: UISwipeGestureRecognizer) {
switch sender.direction {
case UISwipeGestureRecognizerDirection.Right:
print("SWIPED DERECHA")
self.performSegueWithIdentifier("first", sender: nil)
case UISwipeGestureRecognizerDirection.Left:
print("SWIPED IZQUIERDA")
self.performSegueWithIdentifier("second", sender: nil)
default:
break
}
}
You're going about this all wrong. You need to look into interactive custom transitions. So, for example, if you want to swipe left and right to mean push and pop in a navigation controller, then implement the navigation controller's delegate's navigationController:animationControllerForOperation:fromViewController:toViewController: and navigationController:interactionControllerForAnimationController: and go from there.
UISwipeGestureRecognizer should only has one direction allowed, you should use UIPanGestureRecognizer.
let swipe = UIPanGestureRecognizer(target: self, action: "respondToSwipeGesture:")
self.view.addGestureRecognizer(swipe);
func respondToSwipeGesture(sender: UIPanGestureRecognizer) {
let point = sender.velocityInView(self.view)
//left or right
if point.x > 0 {
self.performSegueWithIdentifier("segue1", sender: nil)
}else{
self.performSegueWithIdentifier("segue2", sender: nil)
}
Of course both controllers should be in UINavigationController
For Storyboard settings: