So when ever I long press on a button, it recognizes the long press, but "test" gets called twice. How do I prevent that from happening?
#IBOutlet weak var button2: UIButton!
func longPressMe(){
print("test")
}
func longPressGes(){
let longpress = UILongPressGestureRecognizer(target: self, action: "longPressMe")
longpress.minimumPressDuration = 1
button2.addGestureRecognizer(longpress)
}
override func viewDidLoad() {
super.viewDidLoad()
longPressGes()
}
You have to check the state of the gesture recognizer. Change longPressMe() to something like this:
func longPressMe(recognizer: UILongPressGestureRecognizer) {
guard recognizer.state == .Began else { return }
// do stuff here
}
Have a try, here is how to use #selector:
func longPressMe(recognizer: UILongPressGestureRecognizer) {
// do stuff here
}
func longPressGes(){
let longpress = UILongPressGestureRecognizer(target: self, action: #selector(yourViewController.longPressMe(_:)))
longpress.minimumPressDuration = 1
button2.addGestureRecognizer(longpress)
}
Related
I want to trigger two action on button click and button long click. I have add a UIbutton in my interface builder. How can i trigger two action using IBAction can somebody tell me how to archive this ?
this is the code i have used for a button click
#IBAction func buttonPressed (sender: UIButton) {
....
}
can i use this method or do i have to use another method for long click ?
If you want to perform any action with single tap you and long press the you can add gestures into button this way:
#IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, #selector (tap)) //Tap function will call when user tap on button
let longGesture = UILongPressGestureRecognizer(target: self, #selector(long)) //Long function will call when user long press on button.
tapGesture.numberOfTapsRequired = 1
btn.addGestureRecognizer(tapGesture)
btn.addGestureRecognizer(longGesture)
}
#objc func tap() {
print("Tap happend")
}
#objc func long() {
print("Long press")
}
This way you can add multiple method for single button and you just need Outlet for that button for that..
#IBOutlet weak var countButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
addLongPressGesture()
}
#IBAction func countAction(_ sender: UIButton) {
print("Single Tap")
}
#objc func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
func addLongPressGesture(){
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
longPress.minimumPressDuration = 1.5
self.countButton.addGestureRecognizer(longPress)
}
Why not create a custom UIButton class, create a protocol and let the button send back the info to delegte. Something like this:
//create your button using a factory (it'll be easier of course)
//For example you could have a variable in the custom class to have a unique identifier, or just use the tag property)
func createButtonWithInfo(buttonInfo: [String: Any]) -> CustomUIButton {
let button = UIButton(type: .custom)
button.tapDelegate = self
/*
Add gesture recognizers to the button as well as any other info in the buttonInfo
*/
return button
}
func buttonDelegateReceivedTapGestureRecognizerFrom(button: CustomUIButton){
//Whatever you want to do
}
I am trying to use the long press button function but am not sure how to pass the tag of the button to the function. I have an array of buttons called ChannelButton. The long button press works with the code below.
for button in ChannelButton {
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(sender:)))
button.addGestureRecognizer(longPressGestureRecognizer)
}
func handleLongPress(sender: UILongPressGestureRecognizer) {
doSomeFunction(NeedToPassTheButtonsTagHere)
}
But I need it to modify it to be something like this
for button in ChannelButton {
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(sender:, button.tag)))
button.addGestureRecognizer(longPressGestureRecognizer)
}
func handleLongPress(sender: UILongPressGestureRecognizer, buttontag) {
doSomeFunction(buttontag)
}
I know this doesn't work but I'm not sure how to go about it.
A UIGestureRecognizer has a view property that is the view that it is attached to. In your case, it will be your button. Use it to get to your button's tag:
func handleLongPress(sender: UILongPressGestureRecognizer) {
guard let button = sender.view as? UIButton else { return }
doSomeFunction(button.tag)
}
You're trying to add an EXTRA parameter (an int) to an IBAction selector. You can't do that. IBActions have one of 3 selectors:
#IBAction func actionNoParams() {
}
#IBAction func actionWSender(_ sender: Any) {
}
#IBAction func actionWSenderAndEvent(_ sender: Any, forEvent event: UIEvent) {
}
One solution would be to look for the location of your long press gesture, and then check what button has that location.
func handleLongPress(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizerState.began {
let location = sender.location(in: self.view)
for button in ChannelButton {
if button.frame.contains(location) {
//This is the button that is pressed
//Do stuff
}
}
}
}
Remember to conform to UIGestureRecognizerDelegate
I had to create a new thread bcoz it's driving me crazy and all the other answers online are exactly the same. I have done this countless of times but I cannot see what I am missing for the life of me. I am using a "test" view controller just to get the tap gesture working but it isn't working at all... I am fairly certain that I am setting this up correctly, as this is how I've always implemented it in the past: (yes, I have checked the box for isUserInteractionEnabled). I am even implementing this on a different viewcontroller this exact way and it is working...
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(tap)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
#objc func wasTapped() {
print("tapped")
}
}
I have also tried adding the parameters to wasTapped:
#objc func wasTapped(gestureRecognizer: UITapGestureRecognizer) {
print("tapped")
}
You are saying:
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(tap)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
The problem is the last line:
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
You cannot just say let tap like that in the middle of nowhere. You are implicitly making an instance property. But you cannot initialize an instance property with a target of self, because self does not exist at the time an instance property is initialized. (I regard the fact that that code even compiles as a bug, and have reported it as such.)
Move that line to the start of viewDidLoad, like this:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped))
view.addGestureRecognizer(tap)
}
Try something like this
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(wasTapped(sender:)))
tap.numberOfTapsRequired = 1 // Default value
view.isUserInteractionEnabled = true
view.addGestureRecognizer(tap)
}
#objc func wasTapped(sender: UITapGestureRecognizer) {
print("tapped")
}
You have to enable interaction if you want to use gesture recognizers for standard UIView's
Add view.isUserInteractionEnabled = true in your viewDidLoad.
var tapGesture = UITapGestureRecognizer()
take a view and set IBOutlet like:
#IBOutlet weak var viewTap: UIView!
Write pretty code on viewDidLoad() like:
tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.myviewTapped(_:)))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
viewTap.addGestureRecognizer(tapGesture)
viewTap.isUserInteractionEnabled = true
this method is calling when tap gesture recognized:
#objc func myviewTapped(_ sender: UITapGestureRecognizer) {
if self.viewTap.backgroundColor == UIColor.yellow {
self.viewTap.backgroundColor = UIColor.green
}else{
self.viewTap.backgroundColor = UIColor.yellow
}
}
Is there an easy way to deselect an NSTextField after pressing enter?
First you will need to make your view controller the delegate of your text field. Then you override NSControl instance method controlTextDidEndEditing(_:), get your textfield current editor selected range
and from the main thread set it back to your textfield:
import Cocoa
class ViewController: NSViewController, NSTextFieldDelegate {
#IBOutlet weak var textField: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
override func controlTextDidEndEditing(_ obj: Notification) {
if let selectedRange = textField.currentEditor()?.selectedRange {
DispatchQueue.main.async {
self.textField.currentEditor()?.selectedRange = selectedRange
}
}
}
}
Here is one way I did it.
By disabling it with isSelectable and isEditable and then setting a timer to re-enable it after 0.5s
#IBAction func timeCodeChanged(_: NSTextField) {
timecodeLabel.isSelectable = false
timecodeLabel.isEditable = false
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(reEnableLabel), userInfo: nil, repeats: false)
}
#objc func reEnableLabel() {
timecodeLabel.isSelectable = true
timecodeLabel.isEditable = true
}
Swift playground on iOS is good IDE for new programmers , and apple provide a virtual keyboard for programming , we can swipe the single button to input multi characters ,including “, ; : / “ …. , I want to realize the feature in my programme . How to implement this functionality? Using UIGestureRecognizerDelegate ? pan ? how to realized the animation that appeared in button when swipping ?
here is my code:
import UIKit
class myViewController: UIViewController, UIGestureRecognizerDelegate {
#IBOutlet weak var mybutton1: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(buttonPressed(_:)))
let moveRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(moved(_:)))
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(pan(_:)))
let longgestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longLabelPressed(_:)))
longgestureRecognizer.minimumPressDuration = 1 //.001
mybutton1.isUserInteractionEnabled = true;
mybutton1.addGestureRecognizer(gestureRecognizer)
mybutton1.addGestureRecognizer(moveRecognizer)
mybutton1.addGestureRecognizer(panRecognizer)
mybutton1.addGestureRecognizer(longgestureRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func moved(_ recognizer:UILongPressGestureRecognizer){
print("moved !!!!")
}
func pan(_ recognizer:UILongPressGestureRecognizer){
print("pan !!!!")
}
func longLabelPressed(_ recognizer:UILongPressGestureRecognizer){
// if let label = recognizer.view as? UIButton {
if recognizer.state == .began {
//label.textColor = UIColor.red
print("longlabelPressed begin !")
}
if recognizer.state == .ended {
//label.textColor = UIColor.black
print("longlabelPressed end !")
}
}
func buttonPressed(_ recognizer:UITapGestureRecognizer) {
print("labelPressed !")
}
}
//=============