user3069232
user3069232

Reputation: 8995

Creating a simple label that switches text when tapped in swift

Swift 4.0 iOS 11.x Just when you think your getting the hang of things, you realise you missed something critical. Wanted to create a label that changed itself when you tapped it. Created this sub class of label.

import UIKit

class TapText: UILabel {

private var changableValues: String = "NESW"
private var currentPosition:Int = 0

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
    print("required ")
    let tap = UITapGestureRecognizer(target: self, action:  Selector(("tapFunction:")))
    self.addGestureRecognizer(tap)
}

required override init(frame: CGRect) {
    super.init(frame: frame)
     print("required override")
    let tap = UITapGestureRecognizer(target: self, action:  Selector(("tapFunction:")))
    self.addGestureRecognizer(tap)
}

func tapFunction(sender:UITapGestureRecognizer) {
    print("tapped")
    self.text = String(Array(changableValues)[currentPosition])
    if currentPosition < changableValues.count {
        currentPosition += 1
    } else {
        currentPosition = 0
    }
}

}

Which I thought would work. As Nilish just pointed out I forgot to add userInteractive, but when I do I get a crash.

2018-03-12 11:14:40.283502+0100 Blah[952:382749] -[Blah.TapText tapFunction:]: unrecognized selector sent to instance 0x111a57700 2018-03-12 11:14:40.285213+0100 QRCodeReader[952:382749] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Blah.TapText tapFunction:]: unrecognized selector sent to instance 0x111a57700' * First throw call stack: (0x184633164 0x18387c528 0x184640628 0x18dfae188 0x184638b10 0x18451dccc 0x18e28aca4 0x18e28f298 0x18dd67a14 0x18dc1eb50 0x18e278b08 0x18e278678 0x18e2777d4 0x18dc1ce5c 0x18dbede7c 0x18e54330c 0x18e545898 0x18e53e7b0 0x1845db77c 0x1845db6fc 0x1845daf84 0x1845d8b5c 0x1844f8c58 0x1863a4f84 0x18dc515c4 0x100887c3c 0x18401856c) libc++abi.dylib: terminating with uncaught exception of type NSException

--- added the _ bar and @objc directive, now works... looks like this...

required override init(frame: CGRect) {
    super.init(frame: frame)
     print("fcuk12032018 required override")
    let tap = UITapGestureRecognizer(target: self, action:  #selector(tapFunction))
    self.addGestureRecognizer(tap)
}

@objc func tapFunction(_ sender:UITapGestureRecognizer) {
    print("fcuk12032018 tapped")
    self.text = String(Array(changableValues)[currentPosition])
    if currentPosition < changableValues.count - 1 {
        currentPosition += 1
    } else {
        currentPosition = 0
    }
}

THANKS Nitish!

Upvotes: 2

Views: 132

Answers (2)

Nitish
Nitish

Reputation: 14123

Set userInteraction to true in initialiser. Then UILabel will respond to gestures.
On the crash issue : Try setting function as func tapFunction(_sender: UITapGestureRecognizer). And set the selector using #selector.

Upvotes: 3

Nicolas Charvoz
Nicolas Charvoz

Reputation: 1509

It seems you missed the userInteractionEnabled in your code. You could add it in your viewController like this :

final class MyViewController: UIViewController {
   @IBOutlet private var myLabel: TapText!

    override func viewDidLoad() {
        super.viewDidLoad()

        myLabel.userInteractionEnabled = true
}

Or directly in your custom class :

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!
    print("required ")
    self.userInteractionEnabled = true
    let tap = UITapGestureRecognizer(target: self, action:  Selector(("tapFunction:")))
    self.addGestureRecognizer(tap)
}

Upvotes: 1

Related Questions