Passing uibutton tag through UILongPressGestureRecognizer? - swift

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

Related

how to add pan gesture on long pressing a button [duplicate]

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
}

How to hide an action button in Swift?

I try to make a button invisible after pressing it. The Connection is an action and not an outlet, because pressing the button will call additional code.
#IBAction func startGame(_ sender: Any) {
print("The game starts...")
}
This does not work, because the button is an action and not an outlet:
startGame.isHidden = true
Is there another way to make an action button invisible and therefore not clickable?
Just create an IBOutlet of the same button and set its isHidden property to true once it's tapped.
#IBAction func startGame(_ sender: Any) {
startGameButton.isHidden = true
}
You can hide button on pressed action this way
#IBAction func startGame(_ sender: Any) {
let pressedButton : UIButton = sender as! UIButton
pressedButton.isHidden = true;
}
You can rewrite your code a little bit as Pratik suggested, so it will look like this:
#IBAction func startGame(_ sender: UIButton) {
sender.isHidden = true
/*
remove button at all from the parent view.
sender.removeFromSuperview()
*/
print("The game starts...")
}

UILongPressGesture gets called twice

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)
}

How to access Siri Remote play/pause button and override menu button

How can I access the play/pause button with the Siri remote and override the menu button? I am currently using this, but it is not working for me. My program crashes when I use this code but only when I call it four example pressing the pause button
The coders is currently positioned below didMoveToView next to touchesBegan
let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
tapGesture.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)]
self.view.addGestureRecognizer(tapGesture)
Your issue is you're calling a function called handleTap: that receives a parameter but you don't have a function called handleTap:. That's what action represents in this line:
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
Change your func tapped() to:
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}
I use the following for Swift 4 (as per question: #selector() in Swift?)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
tapGesture.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)]
self.view.addGestureRecognizer(tapGesture)
#objc func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}
I solved my problem by moving the tapRecognizer selector into my previously set up touch handler function so the code looks like this now:
private func handleTouches(touches: Set<UITouch>) {
for touch in touches {
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)];
self.view!.addGestureRecognizer(tapRecognizer)
}
}
func handleTap(sender: UITapGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Ended {
print("Menu button released")
}
}

numeric keyboard resigns to normal key board in swift

I have a normal set up for a textfield with numberpad and the dismiss keyboard and resignFirstResponder actions in place, but when I tap on the background the numeric keyboard changes to the normal keyboard and then when I tap the background again the keyboard dismisses - STRANGE! How can I dismiss the numeric keyboard with one tap to the background?
self.textField.delegate = self
textField.keyboardType = UIKeyboardType.DecimalPad
#IBAction func tapBackground(sender: AnyObject) {
view.endEditing(true)
}
#IBAction func viewTapped(sender: AnyObject) {
textField.resignFirstResponder()
}
Try following this may help you :)
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: "handleTapGesture:")
tap.delegate = self
self.view.addGestureRecognizer(tap)
}
// MARK: - UITapGestureRecognizer
func handleTapGesture(gesture : UITapGestureRecognizer) {
self.view.endEditing(true)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool
{
return true
}