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

Posted

技术标签:

【中文标题】引用以编程方式创建的 UI 元素【英文标题】:Referring to programmatically created UI elements 【发布时间】: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。

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

【问题讨论】:

【参考方案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)")
        
    

注意这里发生了什么:

    我们使用 flatMap 丢弃所有不是 UIlabels 的子视图。 我们使用 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

以上是关于引用以编程方式创建的 UI 元素的主要内容,如果未能解决你的问题,请参考以下文章

如何访问 Xamarin.Forms 中以编程方式创建的 UI 元素:timepicker

如何以编程方式导航 WPF UI 元素制表位?

如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?

多个ListViews在android中以编程方式创建

如何以编程方式调用 jQuery UI Draggable 拖动开始?

使用 Objective-C 中的 Xcode 在 iOS 中以编程方式制作 UI 元素