Reputation: 312
I have created a custom UIControl. The UIControl contains multiple items like drawings and labels.
I want to be able to catch a tap on a label inside the ViewController. Note that I add components inside the UIControl and that I am not using NIB/XIB files).
I am rather new at swift/iOS development. I am working in XCode 10.3 and swift 5. I did some Google searches which did not help me much. I also found this reference (How to add touch event for custom uicontrol and controller?), but I could not get that to work either.
I have added a minimal code example (based on a new project).
\\ File: SomeUI.swift
import UIKit
@IBDesignable
class SomeUI: UIControl {
private var componentsAdded = false
private let labelOne = UILabel()
private let labelTwo = UILabel()
override func draw(_ rect: CGRect) {
if !componentsAdded {
componentsAdded = true
self.addSubview(labelOne)
labelOne.text = "one"
labelOne.sizeToFit()
self.addSubview(labelTwo)
labelTwo.text = "two"
labelTwo.sizeToFit()
}
labelOne.center = CGPoint(x: 10, y: 10)
labelTwo.center = CGPoint(x: 10, y: 40)
}
}
\\ File: ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var someLabel: UILabel!
func changeLabel() {
// switch sender {
// case labelOne: someLabel.text = "one"
// case labelOne: someLabel.text = "two"
// default: println("other")
// }
}
}
The Main.storyboard looks like this:
I would like to be able to implement the changeLabel()
function in the ViewController.swift. Or implement something similar in functionality, such that it "catches" the tap on the UILabel and knows which UILabel was tapped.
Upvotes: 2
Views: 1566
Reputation: 9925
First of all, all interactions with UILabel are disabled by default. To change it, set isUserInteractionEnabled to true.
import UIKit
@IBDesignable
class SomeUI: UIControl {
private var componentsAdded = false
let labelOne = UILabel()
private let labelTwo = UILabel()
required init?(coder: NSCoder) {
super.init(coder: coder)
labelOne.isUserInteractionEnabled = true
}
override func draw(_ rect: CGRect) {
if !componentsAdded {
componentsAdded = true
self.addSubview(labelOne)
labelOne.text = "one"
labelOne.sizeToFit()
self.addSubview(labelTwo)
labelTwo.text = "two"
labelTwo.sizeToFit()
}
labelOne.center = CGPoint(x: 10, y: 10)
labelTwo.center = CGPoint(x: 10, y: 40)
}
}
\\ File: ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBOutlet weak var someLabel: UILabel!
@IBOutlet weak var sui: SomeUI!
@IBAction func changeLabel(_ gestureRecognizer: UITapGestureRecognizer) {
let view = gestureRecognizer.view
let loc = gestureRecognizer.location(in: view)
let subview = sui.hitTest(loc, with: nil)
switch subview {
case sui.labelOne: print("1") someLabel.text = "label one tapped"
case sui.labelTwo: print("2") someLabel.text = "label two tapped"
default: print("0") someLabel.text = "TAPPIO?" }
}
}
In Storyboard add a Tap Gesture Recognizer and set its "Sent Actions" to "changeLabel", "Referencing outlet collections" to your custom SomeUI IBOutlet referenced here by "sui" property
@IBOutlet weak var sui: SomeUI!
Upvotes: 2