swift 5 如何为自定义UIControl添加触摸事件并判断触摸项

How to add touch event for custom UIControl and determine the touched item in swift 5

我创建了一个自定义 UIControl。 UIControl 包含多个项目,例如绘图和标签。

我希望能够在 ViewController 内的标签上点击。 请注意,我在 UIControl 中添加了组件并且我没有使用 NIB/XIB 文件)。

我在 swift/iOS 开发方面相当陌生。我在 XCode 10.3 和 swift 5 中工作。我做了一些 Google 搜索,但对我帮助不大。我也找到了这个参考资料 (),但我也无法使用它。

我添加了一个最小的代码示例(基于一个新项目)。

\ 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")
//        }
    }
}

Main.storyboard 看起来像这样:

(https://postimg.cc/V5h7fdFf)

我希望能够在 ViewController.swift 中实现 changeLabel() 功能。或者实现类似的功能,这样它 "catches" 轻按 UILabel 并知道哪个 UILabel 被轻按。

首先,默认情况下禁用与 UILabel 的所有交互。要更改它,请将 isUserInteractionEnabled 设置为 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?" }
        }
    }

在 Storyboard 中添加一个 Tap Gesture Recognizer 并将其 "Sent Actions" 设置为 "changeLabel","Referencing outlet collections" 到 "sui" 属性 此处引用的自定义 SomeUI IBOutlet

@IBOutlet weak var sui: SomeUI!