Ios Xcode&;Swift-在UIScrollView内部检测用户对UIView的触摸
我正在创建一个类似于Flappy Bird的游戏,但用户将手指放在屏幕上躲避障碍物,而不是点击使小鸟飞翔 我通过使用UIScrollView来实现这一点,其中UIView被用作障碍。当用户触摸UIView时,游戏结束 如何从UIScrollView中检测用户对UIView的触摸?我正在使用带有Xcode Beta 4的Swift 编辑:这是游戏的截图Ios Xcode&;Swift-在UIScrollView内部检测用户对UIView的触摸,ios,xcode,uiview,uiscrollview,swift,Ios,Xcode,Uiview,Uiscrollview,Swift,我正在创建一个类似于Flappy Bird的游戏,但用户将手指放在屏幕上躲避障碍物,而不是点击使小鸟飞翔 我通过使用UIScrollView来实现这一点,其中UIView被用作障碍。当用户触摸UIView时,游戏结束 如何从UIScrollView中检测用户对UIView的触摸?我正在使用带有Xcode Beta 4的Swift 编辑:这是游戏的截图 如您所见,用户在向上滚动时在灰色块(UIView)之间移动手指。您可以通过编程方式添加手势识别器,如下所示 var touch = UITapG
如您所见,用户在向上滚动时在灰色块(UIView)之间移动手指。您可以通过编程方式添加手势识别器,如下所示
var touch = UITapGestureRecognizer(target:self, action:"action")
scrollView.addGestureRecognizer(touch)
但是,此手势识别器不适用于您。UIAPTgestureRecognitor将只返回点击,而不是点击并按住,并且UILongPressgestureRecognitor不提供有关位置的信息,因此您希望使用UIPangestureRecognitor。它不断地告诉你触摸移动了多远
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)
}
你可以使用恒定的“平移”来移动你的物体,它表示人滑动手指的距离。使用该值加上鸟的位置将鸟移动到新点。调用此函数后,必须将转换重置为零
编辑:根据游戏的格式,这段代码应该是最好的方法
总之,找到手指位置的代码应该如下所示
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,包含当前触摸的位置,无论手指滑向何处。由于我不知道如何创建要避免的视图,您必须使用currentLocation的y坐标来确定在该y处要避免的视图的x边界,并使用<或>比较器来确定触摸的x边界是否在这些视图中
注意:您必须声明位置,以便可以在handlePan中访问它
var location : CGPoint = CGPointZero
通过将滚动视图的
userInteractionEnabled
设置为NO
,视图控制器将开始接收触摸事件,因为UIViewController
是UIResponder
的子类。您可以覆盖视图控制器中的一个或多个方法以响应这些触摸:
- 触摸开始:withEvent:
- 触摸移动:withEvent:
- touchesEnded:withEvent:
- 触摸已取消: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's 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's 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!")
}
}
}
}
这看起来不错,但是当用户的手指触摸其中一个UIView时,我需要做什么才能让应用程序发送消息或其他什么?我不需要移动一只鸟或任何东西,因为只有用户的手指在互动和躲避障碍。当用户触摸多个UIView中的一个时,游戏将结束。你误解了这个问题:没有鸟:游戏是关于将手指放在屏幕上并避开障碍物。注意。你应该做的是使用touchsbegind方法来找到触摸的初始y值,然后在我给出的代码中添加常量平移的y值,然后使用一些逻辑来找出这些值是否与视图控制器的边界重叠。这是一个好方法。然而,它不是在调用touchesMoved时重新定义了touch吗?效率或许可以有所提高。CGRectContainsPoint是查找位置的方法,但是您需要在每侧的UIView上调用它两次。没错,只要用户不停地移动手指,它确实会调用TestTouchs。但是OP可能会用一些代码来代替
println(“游戏结束!”)
,这些代码会在第一次接触时将当前屏幕替换为游戏结束屏幕,所以我认为这不会是一个问题。您是对的,CGRectContainsPoint
至少需要调用两次。但是obstacleViews数组包含所有障碍视图,包括两个“关键”视图,所以这很好。如果性能低于标准,OP始终可以优化代码,以仅检查两个“关键”视图或当前可见的视图。公平。所有的代码都在这里,也许可以创建另一个功能来检查初始触摸。你能发布一个swift 3版本吗?