【问题标题】:Referring to programmatically created UI elements引用以编程方式创建的 UI 元素
【发布时间】:2017-11-25 12:48:28
【问题描述】:

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

    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:) 方法中的“发送者”访问属性,因为发送者是 UILongPressGestureRecognizer。

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

【问题讨论】:

    标签: ios swift3


    【解决方案1】:

    首先,我会保留和排列对所有标签的引用,这样您就不必遍历所有子视图来找到它们,并首先保持最高 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({$0 as? UILabel}).last(where: { $0.bounds.contains(sender.location(in: $0))}) {
                print("You pressed: \(label)")
            }
        }
    }
    

    注意这里发生了什么:

    1. 我们使用 flatMap 丢弃所有不是 UIlabels 的子视图。
    2. 我们使用 last 来查找数组中的最后一项 ( 因为根据 UIView.subviews,最顶部的视图是最后一个),其中触摸位于该视图的边界内。

    【讨论】:

      【解决方案2】:

      在创建标签时简单添加此代码

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

      【讨论】:

      • 但是长按呢?我只是触摸没有问题
      • 参考此链接长按long press
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      相关资源
      最近更新 更多