我如何在 swift 中创建一个按钮,它会感应您触摸按钮的位置,并为您提供两个值(x 轴,y 轴)
How do I create a button in swift, which senses where on the button you touch it, and gives you two values (x-axis, y-axis)
我想在 swift 中创建一个按钮,它有两个轴 (x, y),并且可以感知用户触摸它的位置,并基于此设置一个介于 0 和 1 之间的值x 和 y。
我该怎么做?
编辑:针对@Duncan C 指出我的错误更新了答案。
您需要创建自定义“按钮”而不是使用 UIButton 来实现此目的。有两种可能的方法可以做到这一点:
创建一个 UIView 来充当按钮,添加手势识别器来检测触摸,以及所有必要的方法使其按照您的意愿运行。然后你可以使用手势识别器 location(ofTouch touchIndex: Int, in view: UIView?) -> CGPoint
来确定触摸的位置。根据您要求的复杂性,这可能需要大量工作。
子类 UICOntrol 以创建您的按钮。 UIControl 具有内置的所有触摸和事件处理支持,因此您无需重新发明轮子。您需要做的就是覆盖方法 beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool
我总是会选择第二个选项,因为你可以免费获得这么多。
这是一个可以让您入门的按钮的简单示例:
class BigButton: UIControl {
override init(frame: CGRect){
super.init(frame: frame)
let label = UILabel()
label.text = "Big Button"
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: self.centerXAnchor),
label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
backgroundColor = .systemMint
addTarget(self, action: #selector(tapped), for: .touchUpInside)
}
@objc func tapped() {
print("button tapped")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//here's the key method you need to get the touch location:
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
super.beginTracking(touch, with: event)
//iirc overridden method can be omitted, as I think all the default implementation does is return true.
// It seems to work either way. Check the docs if you are bothered.
let touches = event?.touches(for: self)
if let location = touches?.first?.location(in: self) {
print(location)
}
return true
}
}
对于这个简单的示例,每次在按钮范围内单击时,都会触发绑定操作和位置识别。
在不同区域多次点击它,控制台输出为
(92.5, 112.5)
button tapped
(14.0, 12.0)
button tapped
(557.0, 14.5)
button tapped
(513.0, 647.0)
button tapped
(436.0, 563.0)
button tapped
(436.0, 563.0)
button tapped
(40.5, 25.0)
button tapped
如果您希望这些值在 0 ... 1 范围内,您需要将它们计算为视图大小的一部分。
我想在 swift 中创建一个按钮,它有两个轴 (x, y),并且可以感知用户触摸它的位置,并基于此设置一个介于 0 和 1 之间的值x 和 y。
我该怎么做?
编辑:针对@Duncan C 指出我的错误更新了答案。
您需要创建自定义“按钮”而不是使用 UIButton 来实现此目的。有两种可能的方法可以做到这一点:
创建一个 UIView 来充当按钮,添加手势识别器来检测触摸,以及所有必要的方法使其按照您的意愿运行。然后你可以使用手势识别器
location(ofTouch touchIndex: Int, in view: UIView?) -> CGPoint
来确定触摸的位置。根据您要求的复杂性,这可能需要大量工作。子类 UICOntrol 以创建您的按钮。 UIControl 具有内置的所有触摸和事件处理支持,因此您无需重新发明轮子。您需要做的就是覆盖方法
beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool
我总是会选择第二个选项,因为你可以免费获得这么多。
这是一个可以让您入门的按钮的简单示例:
class BigButton: UIControl {
override init(frame: CGRect){
super.init(frame: frame)
let label = UILabel()
label.text = "Big Button"
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: self.centerXAnchor),
label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
backgroundColor = .systemMint
addTarget(self, action: #selector(tapped), for: .touchUpInside)
}
@objc func tapped() {
print("button tapped")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//here's the key method you need to get the touch location:
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
super.beginTracking(touch, with: event)
//iirc overridden method can be omitted, as I think all the default implementation does is return true.
// It seems to work either way. Check the docs if you are bothered.
let touches = event?.touches(for: self)
if let location = touches?.first?.location(in: self) {
print(location)
}
return true
}
}
对于这个简单的示例,每次在按钮范围内单击时,都会触发绑定操作和位置识别。 在不同区域多次点击它,控制台输出为
(92.5, 112.5)
button tapped
(14.0, 12.0)
button tapped
(557.0, 14.5)
button tapped
(513.0, 647.0)
button tapped
(436.0, 563.0)
button tapped
(436.0, 563.0)
button tapped
(40.5, 25.0)
button tapped
如果您希望这些值在 0 ... 1 范围内,您需要将它们计算为视图大小的一部分。