问题
I have 3 buttons in my UI that ultimately will perform similar to keys on a piano. Either of the 3 buttons may get tapped to perform that particular buttons actions, but the user can 'slide' their finger off onto the next button to perform button 2's action.
I did some searching and it looks like a touchesBegan method detecting the location of the tap is best. My attempt is below:
@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
(I don't have any action events tied to the 3 buttons, because I thought touchesBegan will cover that.)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
var touch: UITouch = event!.allTouches()!.first!
var location: CGPoint = touch.locationInView(touch.view!)
if CGRectContainsPoint(button1.frame, location){
print("button 1")
}
else if CGRectContainsPoint(button2.frame, location) {
print("button 2")
}
else if CGRectContainsPoint(button3.frame, location) {
print("button 3")
}
}
Nothing prints to the console when I test this. I tested both tapping and swiping across buttons. Should I be using UIViews instead of UIButtons? Should I be using actions on the buttons? This is for Swift 2.0. Thank you.
EDIT
I have a working prototype much closer to how I envisioned this functioning. This thread here: Using iOS pan gesture to highlight buttons in grid pointed me in the direction of using a pangesture on the buttons superview.
var touchPoint = CGPoint()
var myGesture = UIPanGestureRecognizer()
viewDidLoad:
myGesture = UIPanGestureRecognizer(target: self, action: Selector("panDetected:"))
myGesture.maximumNumberOfTouches = 1
view.addGestureRecognizer(myGesture)
.
func panDetected(sender : UIPanGestureRecognizer) {
touchPoint = sender.locationInView(self.view)
if CGRectContainsPoint(button1.frame, touchPoint) {
button1Func()
}
else if CGRectContainsPoint(button2.frame, touchPoint) {
button2Func()
}
else if CGRectContainsPoint(button3.frame, touchPoint) {
button3Func()
}
The above DOES work, however, button1Func / button2Func / button3Func all contain an animation block. When the finger is dragged within the buttons, it fires the method every time a movement is detected. I just need for this to happen once. I tried adding this to a state == .Began statement, but that prevents any functionality once the finger leaves the first tapped button.
Is there any way I can fire those methods (button1Func / button2Func / button3Func) just ONCE inside the pan gesture once the finger is inside the bounds of each of the 3 buttons? I will be happy to clarify this if it's confusing. THANKS.
回答1:
There are a whole bunch of control events you can tie to IBActions. Take a look at the UIControlEvents
enum. You probably want to add actions for UIControlEventTouchDragInside
, UIControlEventTouchDragEnter
and a few others.
来源:https://stackoverflow.com/questions/38064963/slide-finger-across-3-buttons-xcode-swift