I'm trying to make a button for Taking pictures and recording videos. When a long press is made it will record and 1 tap will take a picture. when button is being pressed i want to transform it to create a effect. however the began and ended is not being triggered since it is not transforming?
func centerButtonPressedDown(sender: UITapGestureRecognizer) {
if !pictureTaken {
delegate?.didLongTapCameraButton()
} else {
}
}
func centerButtonClicked(sender: UITapGestureRecognizer) {
if sender.state == .began {
self.centerButton.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
} else if sender.state == .ended {
self.centerButton.transform = CGAffineTransform.identity
}
}
CenterButton
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(centerButtonClicked)) //Tap function will call when user tap on button
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(centerButtonPressedDown))
tapGesture.numberOfTapsRequired = 1
centerButton.addGestureRecognizer(tapGesture)
centerButton.addGestureRecognizer(longGesture)
I tried your code brother first.It shows me error.Then i modified the code it works fine.
let tapGesture = UITapGestureRecognizer(target: self, action:Selector("centerButtonClicked:")) //Tap function will call when user tap on button
let longGesture = UILongPressGestureRecognizer(target: self, action:Selector("centerButtonPressedDown:"))
tapGesture.numberOfTapsRequired = 1
centerButton.addGestureRecognizer(tapGesture)
centerButton.addGestureRecognizer(longGesture)
func centerButtonPressedDown(sender: UILongPressGestureRecognizer) {
if sender.state == .Began {
print("long press began")
}
else if sender.state == .Ended {
print("long press Ended")
}
}
func centerButtonClicked(sender: UITapGestureRecognizer) {
print("tap is detected")
}
When I single tap the button the printed result is
tap is detected
When I long press the button the printed result is
long press began
long press Ended
Related
Here is my code for a long press. When I long-press the button, it keeps getting called. How do I set it up so it only gets called once and then gets called again only once the finger is release and the long press is started again?
let tapGesture = UITapGestureRecognizer(target: self, action: #selector (tap))
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(long))
tapGesture.numberOfTapsRequired = 1
self.reminderButton.addGestureRecognizer(tapGesture)
self.reminderButton.addGestureRecognizer(longGesture)
use this code in your selector
#objc func gestureAction(gesture: UIGestureRecognizer) {
if let longPress = gesture as? UILongPressGestureRecognizer {
if longPress.state == UIGestureRecognizer.State.began {
} else {
}
}
I wanted to implement a UIScrollView that scrolls up and down on button press. What I want is that the scroll view keeps on scrolling smoothly when the button is pressed (in the pressed state). And when I left the button, scrolling should stop. How can I implement this functionality?
I have also attached a screenshot of my view that contains scrollview and up/down arrow buttons.
Note: what I want is that whenever user press the button and keeps on holding his finger on it, the scrollview continues to scroll (unless it reaches the bottom end). And when he left his finger from the button, scrolling should stop. Is there any way to implement such functionality?
contentOffset is what you want. UIScrollView has such property (and of course its subclasses, the UITableView and UICollectionView).
What's a bit tricky in this is how you get to fire up your button while the user hold-press on it. To do this, you would need a long tap gesture recognizer, and a timer. See: Press-and-hold button for "repeat fire"
import UIKit
class ViewController: UITableViewController {
var timer: Timer?
#IBAction func longPressUp(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {
self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.up(_:)), userInfo: nil, repeats: true)
} else if sender.state == .cancelled || sender.state == .ended {
print("CANCELED!")
self.timer?.invalidate()
self.timer = nil
}
}
#IBAction func longPressDown(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {
self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.down(_:)), userInfo: nil, repeats: true)
} else if sender.state == .cancelled || sender.state == .ended {
print("CANCELED!")
self.timer?.invalidate()
self.timer = nil
}
}
#IBAction func up(_ sender: Any) {
print("UP!")
let desiredOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y + 50)
self.tableView.setContentOffset(desiredOffset, animated: true)
}
#IBAction func down(_ sender: Any) {
let desiredOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y - 50)
self.tableView.setContentOffset(desiredOffset, animated: true)
}
}
As the title reads, my problem is that my UILongPressGestureRecognizer sometimes does not run the code inside the sender.state = .ended. The .began always runs and works. I have tried to notice pattern but is to infrequent and I have not found a valid pattern or causation. I simply add my UITapGestureRecognizer UILongPressGestureRecognizer to my button:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(normalTap(_:)))
tapGesture.numberOfTapsRequired = 1
camButton.addGestureRecognizer(tapGesture)
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap(_:)))
longGesture.minimumPressDuration = 0.10
camButton.addGestureRecognizer(longGesture)
And then here is my longTap function:
#objc func longTap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
if movieOutput.recordedDuration.seconds == lastRecordDuration || movieOutput.recordedDuration.seconds <= 0.35 {
capturePhoto()
} else {
stopRecording()
}
} else if sender.state == .began {
startCapture()
}
}
I use the longPress for video and photos, and the TapGesture for photos only. Im using AVFoundation.
After receiving assistance from #rmaddy, the solution is basically to implement a .cancelled state action. For some reason the continuous gesture of UILongPressGesture got cancelled. In my code I implemented a `if sender.state == .cancelled.
I know this is old question, but writing for those who are facing issue like me.
You can get sender.state == .possible when tap is ended.
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 want to wire an action such that if the gesture is a tap, it does animates an object in a particular way but if the press duration was more than .5 secs it does something else.
Right now, I just have the animation hooked up. I don't know how I can differentiate between a long press and a tap?
How do I access the press duration to achieve the above?
#IBAction func tapOrHold(sender: AnyObject) {
UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: {
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {
self.polyRotate.transform = CGAffineTransformMakeRotation(1/3 * CGFloat(M_PI * 2))
})
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {
self.polyRotate.transform = CGAffineTransformMakeRotation(2/3 * CGFloat(M_PI * 2))
})
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {
self.polyRotate.transform = CGAffineTransformMakeRotation(3/3 * CGFloat(M_PI * 2))
})
}, completion: { (Bool) in
let vc : AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier("NextView")
self.showViewController(vc as UIViewController, sender: vc)
})
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")
}
Swift 5
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))
self.view.addGestureRecognizer(tapGestureRecognizer)
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressed))
self.view.addGestureRecognizer(longPressRecognizer)
#objc func tapped(sender: UITapGestureRecognizer){
print("tapped")
}
#objc func longPressed(sender: UILongPressGestureRecognizer) {
print("longpressed")
}
For swift2
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
lpgr.minimumPressDuration = 0.5
lpgr.delaysTouchesBegan = true
lpgr.delegate = self
self.featuredCouponColView.addGestureRecognizer(lpgr)
Action
//MARK: - UILongPressGestureRecognizer Action -
func handleLongPress(gestureReconizer: UILongPressGestureRecognizer) {
if gestureReconizer.state != UIGestureRecognizerState.Ended {
//When lognpress is start or running
}
else {
//When lognpress is finish
}
}
For Swift 4.2/ Swift 5
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
lpgr.minimumPressDuration = 0.5
lpgr.delaysTouchesBegan = true
lpgr.delegate = self
self.colVw.addGestureRecognizer(lpgr)
//MARK: - UILongPressGestureRecognizer Action -
#objc func handleLongPress(gestureReconizer: UILongPressGestureRecognizer) {
if gestureReconizer.state != UIGestureRecognizer.State.ended {
//When lognpress is start or running
}
else {
//When lognpress is finish
}
}
Through code without interface builder
// Global variables declaration
var longPressed = false
var selectedRow = 0
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ContactListTableViewController.handleLongPress(_:)))
longPressGesture.minimumPressDuration = 1.0 // 1 second press
longPressGesture.allowableMovement = 15 // 15 points
longPressGesture.delegate = self
self.tableView.addGestureRecognizer(longPressGesture)
}
// Long tap work goes here !!
if (longPressed == true) {
if(tableView.cellForRowAtIndexPath(indexPath)?.accessoryType == .Checkmark){
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
self.selectedRow -= 1
if(self.selectedRow == 0){
self.longPressed = false
}
} else {
self.selectedRow += 1
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
}
} else if(self.selectedRow == 0) {
// Single tape work goes here !!
}
But the only problem is the long press gesture runs two times. If you have found any solution do comment below !
Swift 5 using interface builder
for the normal tap you can simply create a touch up inside action from your button.
for the long press, create an outlet for your button, create the tap gesture recognizer and set it to the button then create the selector method to perform the long press tasks.
#IBOutlet var myButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(addToListButtonLongPress(_:)))
longPressRecognizer.numberOfTouchesRequired = 1
longPressRecognizer.allowableMovement = 10
longPressRecognizer.minimumPressDuration = 0.5
myButton.addGestureRecognizer(longPressRecognizer)
}
// Connected to myButton in interface builder.
#IBAction func myButtonTapped(_ sender: UIButton) {
print("button tapped")
}
#objc func myButtonLongPressed(_ sender: UILongPressGestureRecognizer) {
print("button long pressed")
}