引用以编程方式创建的 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
如何在不“连接”它们的情况下以编程方式访问 NIB 中的 UI 元素?