引用以编程方式创建的 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)")
}
}
}
注意这里发生了什么:
- 我们使用 flatMap 丢弃任何不是 UIlabel 的子视图。
- 我们使用 last 来查找数组中的最后一项 (
因为根据 UIView.subviews),最上面的视图是最后的,触摸在该视图的边界内。
我正在以编程方式创建许多 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)")
}
}
}
注意这里发生了什么:
- 我们使用 flatMap 丢弃任何不是 UIlabel 的子视图。
- 我们使用 last 来查找数组中的最后一项 ( 因为根据 UIView.subviews),最上面的视图是最后的,触摸在该视图的边界内。