Xcode & Swift - обнаружение пользовательского касания UIView внутри UIScrollView
Я создаю игру, похожую на Flappy Bird, но пользователь держит палец на экране и уклоняется от препятствий, вместо того, чтобы нажимать, чтобы птица летала.
Я делаю это, имея UIScrollView, в котором UIView используются как препятствия. Когда пользователь касается UIView, игра заканчивается.
Как определить, как пользователи касаются UIView из UIScrollView? Я использую Swift с Xcode Beta 4.
EDIT: Это скриншот игры
![This is screenshot of the game]()
Как вы можете видеть, пользователь перемещает палец между серыми блоками (UIViews) по мере их прокрутки вверх.
Ответы
Ответ 1
Установив userInteractionEnabled
в NO
для вашего вида прокрутки, контроллер просмотра начнет принимать события касания, так как UIViewController
является подклассом UIResponder
. Вы можете переопределить один или несколько из этих методов в своем контроллере просмотра, чтобы ответить на эти касания:
- touchhesBegan: withEvent:
- touchhesMoved: withEvent:
- touchesEnded: withEvent:
- touchCancelled: withEvent:
Я создал некоторый пример кода, чтобы продемонстрировать, как вы могли это сделать:
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
// This array keeps track of all obstacle views
var obstacleViews : [UIView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Create an obstacle view and add it to the scroll view for testing purposes
let obstacleView = UIView(frame: CGRectMake(100,100,100,100))
obstacleView.backgroundColor = UIColor.redColor()
scrollView.addSubview(obstacleView)
// Add the obstacle view to the array
obstacleViews += obstacleView
}
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
testTouches(touches)
}
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
testTouches(touches)
}
func testTouches(touches: NSSet!) {
// Get the first touch and its location in this view controller view coordinate system
let touch = touches.allObjects[0] as UITouch
let touchLocation = touch.locationInView(self.view)
for obstacleView in obstacleViews {
// Convert the location of the obstacle view to this view controller view coordinate system
let obstacleViewFrame = self.view.convertRect(obstacleView.frame, fromView: obstacleView.superview)
// Check if the touch is inside the obstacle view
if CGRectContainsPoint(obstacleViewFrame, touchLocation) {
println("Game over!")
}
}
}
}
Ответ 2
Вы можете программно добавить распознаватель жестов следующим образом
var touch = UITapGestureRecognizer(target:self, action:"action")
scrollView.addGestureRecognizer(touch)
Однако этот распознаватель жестов не будет работать для вас. UITapGestureRecognizer будет возвращаться только для крана, а не для нажатия и удержания, а UILongPressGestureRecognizer не предоставляет информацию о местоположении, поэтому вы хотите использовать UIPanGestureRecognizer. Он постоянно сообщает вам, как далеко движется сенсор.
var touch = UIPanGestureRecognizer(target:self, action:"handlePan")
scrollView.addGestureRecognizer(touch)
@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
let translation = recognizer.translationInView(self.view)
recognizer.setTranslation(CGPointZero, inView: self.view)
}
Вы можете использовать постоянный "перевод" для перемещения вашего объекта, он представляет собой расстояние, на которое человек скользнул пальцем. Используйте это, а также местоположение вашей птицы, чтобы переместить птицу в новую точку. Вы должны reset преобразовать в ноль после вызова этой функции.
Изменить: в формате вашей игры этот код должен быть лучшим методом.
Итак, все вместе, код для поиска местоположения вашего пальца должен быть следующим.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let location = touch.locationInView(yourScrollView)
}
}
@IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
let translation = recognizer.translationInView(self.view)
var currentLocation : CGPoint = CGPointMake(location.x+translation.x, location.y+translation.y)
recognizer.setTranslation(CGPointZero, inView: self.view)
}
currentLocation - это CGPoint, содержащий местоположение текущего касания, куда палец скользит. Поскольку я не знаю, как вы создаете представления, которых следует избегать, вам придется использовать координату y currentLocation для определения границ x представлений, которые следует избегать при этом y, и использовать < или > компараторы, чтобы определить, находится ли граница x в любом из этих представлений.
Примечание. Вы должны объявить местоположение, чтобы его можно было получить в handlePan
var location : CGPoint = CGPointZero