How to detect UITouch location visible in Swift 3 - swift

I am trying to detect a UITouch event visible.When touch event begins.Currently, I am using below code to detect the touch location.From below code,I can able to print the touch location.Any,help would be greatly appreciated.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
if let touch = touches.first {
let position :CGPoint = touch.location(in: view)
print(position.x)
print(position.y)
}
}
Note: I am not trying to draw a line or anything like a drawing app.I,Just want to see the touch event visibly.When happens.
Thanks in advance.

If you want a circle or something to appear when the user taps the screen, try this:
var touchIndicators: [UIView] = []
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: view)
let touchIndicator = UIView(frame: CGRect(x: location.x - 10, y: location.y - 10, width: 20, height: 20))
touchIndicator.alpha = 0.5
touchIndicator.backgroundColor = UIColor.red
touchIndicator.layer.cornerRadius = 10
self.view.addSubview(touchIndicator)
touchIndicators.append(touchIndicator)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for indicator in touchIndicators {
indicator.removeFromSuperview()
}
touchIndicators = []
}
Pretty straightforward. Add circular views when the user touches the screen and remove them when the user lifts his/her fingers. You can also do this using UITapGestureRecognizer.

Related

drag a SKSprite Node or a UIImage by my finger more accurately, maintain offset?

I am trying to drag a SKSprite Node or a UIImage by my finger more accurately. For example if a touch is registered in the bottom corner of the node and moved, I want to the image to maintain the distance between your finger location and the center of node. Currently the center location jumps to the finger location.
Here is my code, it seems the offset code (touchl - previousLocation) isn't being maintained.
Any suggestions?
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let touchl = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
triangle.position.x = touchl.x + (touchl.x - previousLocation.x)
triangle.position.y = touchl.y + (touchl.y - previousLocation.y)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let touchl = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
let dx = touchl.x - previousLocation.x
let dy = touchl.y - previousLocation.y
triangle.position.x = triangle.position.x + dx
triangle.position.y = triangle.position.y + dy
}
}

get line to remain a perfect 90 degrees when create

My swift code's goal is to get every line to only be able to be place at a 90 degree angle. Right now the code has two points a start and end where the start point is fixed upon touching the uiview. I would the user to be able to touch a point and only be able to extend the line at a 90 degree angle. Look at the gif below for more info. The bottom line is what i am trying to acheive. I think you have to use guard in touches began.
import UIKit
class ViewController2: UIViewController {
#IBOutlet weak var drawingPlace: UIImageView!
var startTouch : CGPoint?
var secondTouch : CGPoint?
var currentContext : CGContext?
var prevImage : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
startTouch = touch?.location(in: drawingPlace)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
secondTouch = touch.location(in: drawingPlace)
if(self.currentContext == nil){
UIGraphicsBeginImageContext(drawingPlace.frame.size)
self.currentContext = UIGraphicsGetCurrentContext()
}else{
self.currentContext?.clear(CGRect(x: 0, y: 0, width: drawingPlace.frame.width, height: drawingPlace.frame.height))
}
self.prevImage?.draw(in: self.drawingPlace.bounds)
let bezier = UIBezierPath()
bezier.move(to: startTouch!)
bezier.addLine(to: secondTouch!)
bezier.close()
UIColor.blue.set()
self.currentContext?.setLineWidth(4)
self.currentContext?.addPath(bezier.cgPath)
self.currentContext?.strokePath()
let img2 = self.currentContext?.makeImage()
drawingPlace.image = UIImage.init(cgImage: img2!)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.currentContext = nil
self.prevImage = self.drawingPlace.image
}
}
The problem is this line:
bezier.addLine(to: secondTouch!)
This causes the line to follow the position of the touch, wherever it is. Instead, drop a perpendicular to the horizontal (I presume that is what you mean by 90 degrees) and add the line to that point on the horizontal. In other words, use the x component of secondTouch, but use as the y component the y component of startTouch.
bezier.addLine(to: CGPoint(x:secondTouch!.x, y:startTouch!.y)

In Xcode how would I get a SkSpriteNode to move up when clicked on?

How do I get the SkSpriteNode to move up when clicked?
-Thanks
https://i.stack.imgur.com/fcOvr.png
lets say your node is called box
use the touches began function
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for _ in touches{
let touch:UITouch = touches.first!
let touchLocation = touch.location(in: self)
box.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
box.physicsBody?.applyImpulse(CGVector(dx: 0, dy:300))
}
}
the applyImpusle method takes an x value to move along the x axis(left or right) and takes a y value to move along the y axis (up or down). set dy accordingly.
rest of it depends on your scene properties like gravity , friction , mass of the box and so on
Without using a physicsBody you can use this code and just change how you move it up (I do it manually just to keep it simple).
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if sprite.contains(location){
sprite.position = CGPoint(x: 0, y: 10)
}

Bullet Firing In Direction Of Tap

So far, my app has a big ball in the middle and a small ball in the middle also. I would like to be able to tap anywhere on the screen and the small ball shoots in that direction. I've heard people say about creating vectors but I can't seem to get these working in swift 3. I am a beginner so sorry about a stupid question!
Here is my code:
var mainBall = SKSpriteNode(imageNamed: "Ball")
override func didMove(to view: SKView) {
mainBall.size = CGSize(width: 300, height: 300)
mainBall.position = CGPoint(x: frame.width / 2, y: frame.height / 2)
self.addChild(mainBall)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let position = touch.location(in: self)
print(position.x)
print(position.y)
}
for touch in (touches) {
touch.location(in: self)
let smallBall = SKSpriteNode(imageNamed: "Ball")
smallBall.position = mainBall.position
smallBall.size = CGSize(width: 100, height: 100)
smallBall.physicsBody = SKPhysicsBody(circleOfRadius: smallBall.size.width / 2)
smallBall.physicsBody?.affectedByGravity = false
self.addChild(smallBall)
}
}
You can use actions to animate SKSprideNodes:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
let newPosition = touch.location(in: self)
...
//assuming self.smallBall exists and is visible already:
[self.smallBall runAction:[SKAction moveTo:newPosition duration:1.0]];
}

Apply impulse to a SKSpriteNode from a user swipe

Can anyone tell me why when I try to apply an impulse to a node like this it disappears?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch:UITouch = touches.first! as UITouch
startPoint = touch.location(in: view)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
defer {
startPoint = nil
}
guard touches.count == 1, let startPoint = startPoint else {
return
}
if let touch = touches.first {
let endPoint = touch.location(in: view)
//Calculate your vector from the delta and what not here
direction = CGVector(dx: endPoint.x - startPoint.x, dy: endPoint.y - startPoint.y)
L1Ball.physicsBody?.applyImpulse(CGVector(dx: direction.dx.hashValue, dy: direction.dy.hashValue))
}
}
I think it has something to do with the way I am using hashValue. I don't know another way to get the values from the CGVector direction. If I try to use direction itself as the impulse vector it just crashes. Any insight? Thanks!
Your code worked for me when I removed the .hashValue from direction.dx and direction.dy (hash values are used for comparisons). Oh and your ball node isn't disappearing. Those hash values are large enough that when you apply them on a ball as a force, the speed of the ball is big enough that by the time the next frame is rendered the ball is off the screen.