引用以编程方式创建的 UI 元素

Referring to programmatically created UI elements

我正在以编程方式创建许多 UI 元素。假设有 50 UI 个标签。 访问标签属性的正确方法是什么? 现在我在 [subview] 数组中为每个标签和下一个搜索标签添加一个标签,并通过 'sender':

获取标签属性
    func buttonTapped(sender: UIButton) {

        for subview in containerView.subviews {

            if let label = subview as? UILabel, label.tag == sender.tag {
// do stuff
}
}
}

不确定这是最优雅的方式,因为如果我们将标签更改为按钮会出现一些问题。

假设:

func createButton() {
    let button = UIButton(frame: CGRect(origin: ...,
                                        size: ...))

    button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)

    let longTap = UILongPressGestureRecognizer(target: self, action: #selector(disableButton(sender:)))
    longTap.minimumPressDuration = 1
    button.addGestureRecognizer(longTap)

    .......
    containerView.addSubview(button)

}

现在我无法通过 disableButton(sender:) 方法中的 'sender' 访问属性,因为发件人是 UILongPressGestureRecognizer。

如果它适用于标签但不适用于按钮,我好像做错了什么。 请指引我正确的方向

创建标签时只需添加此代码

yourLbl.isUserInteractionEnabled = true

并使用 touchesBegan 方法获取您点击的标签

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

   let touch = touches.first
    if let lblView = touch?.view
    {
        if lblView.isKind(of: UILabel.self)
        {
            let yourLbl = lblView as! UILabel

            //Access your clicked lable
        }
    }


}

首先,我会保留所有标签的引用并进行排列,这样您就不必遍历所有子视图来找到它们,并按照最高 z 值在前的顺序排列。但是,如果您不想这样做,这里的代码可以让您在一行中查看;它不是世界上最有效的东西,但对于您的浏览量来说应该没问题。

class ViewController: UIViewController {
    let first = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
    let second = UILabel(frame: CGRect(x: 25, y: 25, width: 100, height: 50))
    override func viewDidLoad() {
        first.text = "first"
        first.backgroundColor = .blue
        second.text = "second"
        second.backgroundColor = .red
        view.addSubview(first)
        view.addSubview(second)
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
        view.addGestureRecognizer(tap)
    }
    @objc func handleTap(sender: UITapGestureRecognizer)  { 
        if let label = view.subviews.flatMap({[=10=] as? UILabel}).last(where: { [=10=].bounds.contains(sender.location(in: [=10=]))}) {
            print("You pressed: \(label)")
        }
    }
}

注意这里发生了什么:

  1. 我们使用 flatMap 丢弃任何不是 UIlabel 的子视图。
  2. 我们使用 last 来查找数组中的最后一项 ( 因为根据 UIView.subviews),最上面的视图是最后的,触摸在该视图的边界内。