I'm using XCode 10.2 with SpriteKit and swift 5 to create a Mac Application, and I cannot for the life of me find a working example of handling click events on a node.
The most updated info I can find suggests using the following:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { }
But XCode errors, saying
Use of undeclared type 'UIEvent'
Use of undeclared type 'UITouch'
I'm not sure how to proceed cause all the info I find suggests using the above code. Everything else is working OK so far though. Here is my GameScene Class:
import SpriteKit
class GameScene: SKScene {
var circle: SKShapeNode = SKShapeNode();
var label: SKLabelNode = SKLabelNode();
var ground: SKShapeNode = SKShapeNode();
/**
* Did Move Callback
*/
override func didMove(to view: SKView) {
initGround(view: view);
initLabel(view: view);
let recognizer = NSClickGestureRecognizer(target: self, action: #selector(tap));
view.addGestureRecognizer(recognizer);
}
/**
* Click Handler
*/
#objc func tap(recognizer: NSGestureRecognizer) {
let viewLocation = recognizer.location(in: view);
let sceneLocation = convertPoint(fromView: viewLocation);
addCircle(view: view!, position: sceneLocation);
}
// Not Working
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
/**
* Init Ground
*/
func initGround(view: SKView) {
let path = CGMutablePath();
path.move(to: CGPoint(x: 0, y: 30));
path.addLine(to: CGPoint(x: view.frame.width, y: 30));
path.addLine(to: CGPoint(x: view.frame.width, y: view.frame.height));
path.addLine(to: CGPoint(x: 0, y: view.frame.height));
path.addLine(to: CGPoint(x: 0, y: 30));
ground.path = path;
ground.lineWidth = 5;
ground.strokeColor = SKColor.brown;
let borderBody = SKPhysicsBody(edgeLoopFrom: path);
borderBody.friction = 5;
self.physicsBody = borderBody;
addChild(ground);
}
/**
* Add Label
*/
func initLabel(view: SKView) {
label = SKLabelNode(text: "No Gravity");
label.name = "no gravity button";
label.position = CGPoint(x: label.frame.width / 2, y: 5);
label.fontSize = 12;
label.fontColor = SKColor.yellow;
label.fontName = "Avenir";
label.isUserInteractionEnabled = true;
addChild(label);
}
/**
* Add Circle
*/
func addCircle(view: SKView, position: CGPoint) {
let size = Int.random(in: 1 ..< 50);
let color = getRandomColor();
circle = SKShapeNode(circleOfRadius: CGFloat(size));
// Set Position
circle.position = position;
// Set Physics
circle.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(size));
circle.physicsBody?.affectedByGravity = false;
circle.physicsBody?.usesPreciseCollisionDetection = true;
circle.physicsBody?.restitution = 1; //0.8
circle.physicsBody?.linearDamping = 0;
circle.physicsBody?.friction = 0; //0.2
circle.physicsBody?.isDynamic = true;
circle.physicsBody?.mass = CGFloat(size);
circle.physicsBody?.allowsRotation = true;
circle.physicsBody?.velocity = CGVector(dx: 0, dy: -1000);
circle.strokeColor = color;
circle.glowWidth = 1.0;
circle.fillColor = color;
addChild(circle)
}
func getRandomColor() -> SKColor {
return SKColor(red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1),
alpha: 1.0)
}
}
Does anyone have experience with using Swift 5 and handling clicks / touches in SpriteKit? Or maybe just why XCode says that UIEvent and UITouch aren't real things?
Thanks!
On Mac, you’ll implement
-(void)mouseDown:(NSEvent *)theEvent {
}
- (void)mouseUp:(NSEvent *)theEvent {
}
- (void)mouseExited:(NSEvent *)theEvent {
}
In each case you will call
CGPoint loc = [theEvent locationInNode:self];
to learn where the click happened within the scene.
User Martin R pointed out the UIEvent and UITouch classes are included only in iOS projects. I'm creating a Mac Application, what I didn't realize was that I already had the click handler in my GameScene class:
override func didMove(to view: SKView) {
let recognizer = NSClickGestureRecognizer(target: self, action: #selector(click));
view.addGestureRecognizer(recognizer);
}
This registers a callback to a click handler, which I already had defined:
/**
* Click Handler
*/
#objc func tap(recognizer: NSGestureRecognizer) {
let viewLocation = recognizer.location(in: view);
let sceneLocation = convertPoint(fromView: viewLocation);
let touchedNode = self.atPoint(sceneLocation);
if let name = touchedNode.name {
if name == "no gravity button" {
print("Touched")
}
}
addCircle(view: view!, position: sceneLocation);
}
I was able to get the clicked node name and act upon it as I originally intended.
Related
So here is my code:
import SpriteKit
import GameplayKit
class GameScene: SKScene {
var ship1 = [2,1]
var ship2 = [1,2]
let jonahSpriteNode = SKSpriteNode(imageNamed: "jonah_spaceship")
let georgeSpriteNode = SKSpriteNode(imageNamed: "george_spaceship")
override func didMove(to view: SKView) {
//var jonahFrames = [SKTexture]()
jonahSpriteNode.position = CGPoint(x: 30, y: frame.midY)
jonahSpriteNode.size = CGSize(width: 100.0, height: 100.0)
addChild(jonahSpriteNode)
georgeSpriteNode.position = CGPoint(x: 628, y: frame.midY)
georgeSpriteNode.size = CGSize(width: 100.0, height: 100.0)
addChild(georgeSpriteNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
var touchLocation = touch.location(in: self)
var angle1 = atan2(jonahSpriteNode.position.y - touchLocation.y , jonahSpriteNode.position.x - touchLocation.x)
var angle = angle1 - CGFloat(Double.pi / 1)
makeCircularRange(to: jonahSpriteNode)
let rotate = SKAction.rotate(toAngle: angle, duration: 1.0)
let move = SKAction.move(to: CGPoint(x: touchLocation.x, y: touchLocation.y), duration: 2.5)
let sequence = SKAction.sequence([rotate, move])
jonahSpriteNode.run(sequence)
}
}
func makeCircularRange(to node: SKNode) {
let range = SKRange(lowerLimit: 0, upperLimit: 400)
let constraint = SKConstraint.distance(range, to: .zero)
node.constraints = [constraint]
}
}
I wanted to display the SKRange by showing upperLimit in a certain color. I tried making nodes around the limit and then coloring the nodes but it just showed a bunch of errors. If you have any ideas please answer.
Something like this:
The sprite node will be in the center and the circle will show where it can move.
You can make a circular shape using range.upperLimit as a radius an add to scene.
func drawCircularRangeBy(range: SKRange) {
let radius = range.upperLimit
let node = SKShapeNode(circleOfRadius: radius)
node.strokeColor = .white
addChild(node)
}
Take a look of this example: https://github.com/Maetschl/SpriteKitExamples/blob/master/CircularRange/CircularRange/GameScene.swift
If you really need dots instead of a line please see this answer: Drawing dashed line in Sprite Kit using SKShapeNode
I'm making a game where the ball is suppose to go through some pipes, and when the player touches the pipes, the game stops. Kind of like flappy bird. The only problem I have is that the initial pipes blocks the entire screen, while the rest of the pipes are placed and randomized exactly as I want. How is this possible?
This is the ball class:
import SpriteKit
struct ColliderType {
static let Ball: UInt32 = 1
static let Pipes: UInt32 = 2
static let Score: UInt32 = 3
}
class Ball: SKSpriteNode {
func initialize() {
self.name = "Ball"
self.zPosition = 1
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.height /
2)
self.setScale(0.7)
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = ColliderType.Ball
self.physicsBody?.collisionBitMask = ColliderType.Pipes
self.physicsBody?.contactTestBitMask = ColliderType.Pipes |
ColliderType.Score
}
}
This is the Random Class:
import Foundation
import CoreGraphics
public extension CGFloat {
public static func randomBetweenNumbers(firstNum: CGFloat, secondNum:
CGFloat) -> CGFloat {
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum -
secondNum) + firstNum
}
}
This is the GameplayScene:
import SpriteKit
class GameplayScene: SKScene {
var ball = Ball()
var pipesHolder = SKNode()
var touched: Bool = false
var location = CGPoint.zero
override func didMove(to view: SKView) {
initialize()
}
override func update(_ currentTime: TimeInterval) {
moveBackgrounds()
if (touched) {
moveNodeToLocation()
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event:
UIEvent?) {
touched = true
for touch in touches {
location = touch.location(in:self)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event:
UIEvent?) {
touched = false
}
override func touchesMoved(_ touches: Set<UITouch>, with event:
UIEvent?) {
for touch in touches {
location = touch.location(in: self)
}
}
func initialize() {
createBall()
createBackgrounds()
createPipes()
spawnObstacles()
}
func createBall() {
ball = Ball(imageNamed: "Ball")
ball.initialize()
ball.position = CGPoint(x: 0, y: 0)
self.addChild(ball)
}
func createBackgrounds() {
for i in 0...2 {
let bg = SKSpriteNode(imageNamed: "BG")
bg.anchorPoint = CGPoint(x: 0.5, y: 0.5)
bg.zPosition = 0
bg.name = "BG"
bg.position = CGPoint(x: 0, y: CGFloat(i) * bg.size.height)
self.addChild(bg)
}
}
func moveBackgrounds() {
enumerateChildNodes(withName: "BG", using: ({
(node, error) in
node.position.y -= 15
if node.position.y < -(self.frame.height) {
node.position.y += self.frame.height * 3
}
}))
}
func createPipes() {
pipesHolder = SKNode()
pipesHolder.name = "Holder"
let pipeLeft = SKSpriteNode(imageNamed: "Pipe")
let pipeRight = SKSpriteNode(imageNamed: "Pipe")
pipeLeft.name = "Pipe"
pipeLeft.anchorPoint = CGPoint(x: 0.5, y: 0.5)
pipeLeft.position = CGPoint(x: 350, y: 0)
pipeLeft.xScale = 1.5
pipeLeft.physicsBody = SKPhysicsBody(rectangleOf: pipeLeft.size)
pipeLeft.physicsBody?.categoryBitMask = ColliderType.Pipes
pipeLeft.physicsBody?.affectedByGravity = false
pipeLeft.physicsBody?.isDynamic = false
pipeRight.name = "Pipe"
pipeRight.anchorPoint = CGPoint(x: 0.5, y: 0.5)
pipeRight.position = CGPoint(x: -350, y: 0)
pipeRight.xScale = 1.5
pipeRight.physicsBody = SKPhysicsBody(rectangleOf: pipeRight.size)
pipeRight.physicsBody?.categoryBitMask = ColliderType.Pipes
pipeRight.physicsBody?.affectedByGravity = false
pipeRight.physicsBody?.isDynamic = false
pipesHolder.zPosition = 5
pipesHolder.position.y = self.frame.height + 100
pipesHolder.position.x = CGFloat.randomBetweenNumbers(firstNum:
-250, secondNum: 250)
pipesHolder.addChild(pipeLeft)
pipesHolder.addChild(pipeRight)
self.addChild(pipesHolder)
let destination = self.frame.height * 3
let move = SKAction.moveTo(y: -destination, duration:
TimeInterval(10))
let remove = SKAction.removeFromParent()
pipesHolder.run(SKAction.sequence([move, remove]), withKey: "Move")
}
func spawnObstacles() {
let spawn = SKAction.run({ () -> Void in
self.createPipes()
})
let delay = SKAction.wait(forDuration: TimeInterval(1.5))
let sequence = SKAction.sequence([spawn, delay])
self.run(SKAction.repeatForever(sequence), withKey: "Spawn")
}
func moveNodeToLocation() {
// Compute vector components in direction of the touch
var dx = location.x - ball.position.x
// How fast to move the node. Adjust this as needed
let speed:CGFloat = 0.1
// Scale vector
dx = dx * speed
ball.position = CGPoint(x:ball.position.x+dx, y: 0)
}
}
I am new to swift and sprite kit and I am developing my first game. I am trying to add a shop to my game, however, I can not get it to work the way that I want to. I have a shop of skins that the user can choose from and what I want is for the user to touch on a skin. If it is locked, then the user may purchase it with in game currency and it automatically shows as their current skin during gameplay. If it isn't locked, then the user may press on it to make it their current skin during gameplay. This is my current code:
import SpriteKit
class SkinsScene: SKScene {
var shopTextContainer = SKShapeNode()
var backtoMenuButton = SKSpriteNode()
var skinsText = SKLabelNode()
var coinBox = SKSpriteNode()
var coins = SKLabelNode()
/// Moveable node in the scrollView
var startY: CGFloat = 0.0
var lastY: CGFloat = 0.0
var moveableArea = SKNode()
//SKINS
let skinsArray = [
["skin0": "Character", "price": "Default", "locked":false],
["skin1": "blueCharacter", "price": "50", "locked": true],
["skin2": "basketballSkin", "price": "150", "locked": true]
]
static var currentSkin = "skin0"
override func didMoveToView(view: SKView) {
/* Setup your scene here */
scene?.backgroundColor = UIColor(red: 31/255, green: 30/255, blue: 30/255, alpha: 1.0)
addTitle()
/// add moveable node
moveableArea.position = CGPointMake(0, 0)
self.addChild(moveableArea)
addSkins()
let bottom = SKLabelNode(fontNamed: "Avenir-Black")
bottom.text = "Bottom"
bottom.fontSize = CGRectGetMaxY(self.frame)/20
bottom.position = CGPoint(x:CGRectGetMidX(self.frame), y:0-CGRectGetMaxY(self.frame)*0.5)
moveableArea.addChild(bottom)
}
func addTitle() {
shopTextContainer = SKShapeNode(rectOfSize: CGSize(width: self.frame.size.width, height: 130))
shopTextContainer.position = CGPoint(x: self.frame.width/2, y: self.frame.height - 65)
shopTextContainer.fillColor = UIColor(red: 133/255, green: 0, blue: 241/255, alpha: 1.0)
shopTextContainer.strokeColor = UIColor.clearColor()
shopTextContainer.zPosition = 20
self.addChild(shopTextContainer)
backtoMenuButton = SKSpriteNode(imageNamed: "backButton")
backtoMenuButton.position = CGPoint(x: -shopTextContainer.frame.width/2 + 55, y: 0)
backtoMenuButton.zPosition = 25
shopTextContainer.addChild(backtoMenuButton)
skinsText.fontName = "DayPosterBlack"
skinsText.fontSize = 50.0
skinsText.text = "Skins"
skinsText.position = CGPoint(x: 0, y: -23)
skinsText.zPosition = 25
shopTextContainer.addChild(skinsText)
coinBox = SKSpriteNode(imageNamed: "coinBox")
coinBox.position = CGPoint(x: 0, y: -50)
coinBox.zPosition = 25
shopTextContainer.addChild(coinBox)
coins.fontName = "DayPosterBlack"
coins.fontColor = UIColor.whiteColor()
coins.position = CGPoint(x: 0, y: -6)
coins.zPosition = 1
coins.text = "0"
coins.fontSize = 16.0
coins.zPosition = 25
coinBox.addChild(coins)
}
func addSkins() {
for i in 0...skinsArray.count-1 {
let shape = SKShapeNode(rectOfSize: CGSize(width: 283, height: 73), cornerRadius: 40.05)
shape.position = CGPoint(x: self.frame.width/2, y: self.frame.height - 105*CGFloat(i) - 215)
shape.strokeColor = UIColor(red: 133/255, green: 0, blue: 241/255, alpha: 1.0)
shape.fillColor = UIColor(red: 1/255, green: 1/255, blue: 1/255, alpha: 0.78)
shape.name = String(format: "skin%d", i)
moveableArea.addChild(shape)
let price = SKLabelNode()
price.text = skinsArray[i]["price"] as? String
price.fontSize = 15.0
price.fontName = "DayPosterBlack"
price.fontColor = UIColor.whiteColor()
price.position = CGPoint(x: 0, y: -30)
shape.addChild(price)
let skin = SKSpriteNode(imageNamed: skinsArray[i][shape.name!] as! String)
skin.zPosition = 1
skin.position = CGPoint(x: 0, y: 4)
shape.addChild(skin)
if skinsArray[i]["locked"] == true {
let locked = SKSpriteNode(imageNamed: "lock")
locked.position = CGPoint(x: -shape.frame.size.width/2 + 50, y: 0)
shape.addChild(locked)
skin.alpha = 0.45
}
else if skinsArray[i]["locked"] == false {
let locked = SKSpriteNode(imageNamed: "unlock")
locked.position = CGPoint(x: -shape.frame.size.width/2 + 50, y: 0)
shape.addChild(locked)
shape.fillColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.4)
skin.alpha = 1.0
}
if shape.name == SkinsScene.currentSkin {
shape.strokeColor = UIColor(red: 65/255, green: 117/255, blue: 5/255, alpha: 1.0)
shape.lineWidth = 3.0
}
}
}
/// Touches began,
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
// store the starting position of the touch
for touch in touches {
let location = touch.locationInNode(self)
let goBack = touch.locationInNode(shopTextContainer)
startY = location.y
lastY = location.y
if backtoMenuButton.containsPoint(goBack){
backtoMenuButton.alpha = 0.7
}
else {
backtoMenuButton.alpha = 1.0
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let goBack = touch.locationInNode(shopTextContainer)
if backtoMenuButton.containsPoint(goBack){
if GameScene.soundOn == true {
self.scene?.runAction(buttonTouched)
}
let scene = ShopScene(size: view!.bounds.size)
scene.scaleMode = .ResizeFill
self.view?.presentScene(scene,transition: SKTransition.fadeWithDuration(0.8))
}
else {
backtoMenuButton.alpha = 1.0
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let currentY = location.y
// Set Top and Bottom scroll distances, measured in screenlengths
let topLimit:CGFloat = 0.0
let bottomLimit:CGFloat = 0.6
// Set scrolling speed - Higher number is faster speed
let scrollSpeed:CGFloat = 1.0
// calculate distance moved since last touch registered and add it to current position
let newY = moveableArea.position.y + ((currentY - lastY)*scrollSpeed)
// perform checks to see if new position will be over the limits, otherwise set as new position
if newY < self.size.height*(-topLimit) {
moveableArea.position = CGPointMake(moveableArea.position.x, self.size.height*(-topLimit))
}
else if newY > self.size.height*bottomLimit {
moveableArea.position = CGPointMake(moveableArea.position.x, self.size.height*bottomLimit)
}
else {
moveableArea.position = CGPointMake(moveableArea.position.x, newY)
}
// Set new last location for next time
lastY = currentY
}
}
You can see that I am making a rectangle with the skin from the array of dictionaries declared before the didMoveToView function. I had some code that attempted to detect the touch of the rectangle, but it isn't working, so I deleted it. I also tried to make a static variable called currentSkin to hold the skin and then pass it to my game scene, but that didn't work for me either. Any help would be appreciated. Thanks!
I don't know if I've understand well your question.
But if you want pass your currentSkin to GameScene, you can use a observe, a delegate or static var.
If you set static var current skin, you must write that variable.
in touch:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
// store the starting position of the touch
for touch in touches {
let location = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(location)
if let name = touchedNode.name {
if string.rangeOfString("skin") != nil {
SkinsScene.currentSkin = name
println(name)
}
}
}
}
Now you can call in GameScene:
let mySkin = SkinsScene.currentSkin
if your GameScene alredy exist, you must use delegate or observe.
Let me know you I understood well your question
Im trying to create a method that when I touch a sprite named StartSprite Through my touchesbegan function it will print out something in my console. But for some reason when I click on the sprite nothing happens. This is my code.
import SpriteKit
class GameScene: SKScene {
let StartSprite = SKSpriteNode(imageNamed: "startLabel")
override func didMoveToView(view: SKView) {
let borderRect = CGRect(x: 0 , y: 0 , width: 400, height: 725)
let welcomeLabel = SKLabelNode(fontNamed: "welcome");
welcomeLabel.text = "Welcome";
welcomeLabel.fontColor = UIColor.whiteColor()
welcomeLabel.fontSize = 65
welcomeLabel.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 150)
self.addChild(welcomeLabel)
//StartLabel
let rectangleBorder = SKShapeNode(rect: borderRect)
rectangleBorder.position = CGPoint(x: 315, y: 25)
rectangleBorder.strokeColor = UIColor.whiteColor()
self.addChild(rectangleBorder)
self.backgroundColor = UIColor.grayColor()
StartSprite.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
self.addChild(StartSprite)
println("Hello")
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
if touchLocation == StartSprite.position{
println("Touches")
}
}
}
Your code requires that you touch exactly the one pixel at StartSprite.position.
Try this instead:
let p = StartSprite.convertPoint(touchLocation, fromNode: self)
if StartSprite.containsPoint(p) {
print("touched StartSprite")
}
If you're going to add more buttons, you might want to do this instead:
let target = nodeAtPoint(touchLocation)
if target == StartSprite {
print("touched StartSprite"
}
// check other buttons here
I have a text field to type the word that, when (auto) and press the button (checkbutton) it should print out (correct). The problem is that it's not working.
When I'm in office touchesBegan: if (TextField.text == "auto") lists me an error:
Use Unresolved identifier "TextField".
When this condition removed as everything works fine and writes to me (correct).
I tried complet function touchesBegan moved to override func didMoveToView (view: SKView) and TextField.text is resolved but it is not working.
I work in SpriteKit
Where I make mistakes ?.
Thank you
Here is my code:
class level1: SKScene{
let logo = SKSpriteNode(imageNamed: "Q1")
let check = SKSpriteNode(imageNamed: "check")
let number = SKSpriteNode(imageNamed: "N1")
override func didMoveToView(view: SKView) {
scene!.scaleMode = .AspectFill
scene!.scaleMode = SKSceneScaleMode.ResizeFill
var background = SKSpriteNode(imageNamed: "Background")
background.size = CGSizeMake(self.size.width, self.size.height)
background.position = CGPointMake(self.size.width/2, self.size.height/2)
self.addChild(background)
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width;
let screenHeight = screenSize.height;
var TextField = UITextField(frame : CGRect(x:10, y:(screenHeight/2.25), width:(screenWidth - 20), height:(screenHeight/15) ))
self.view!.addSubview(TextField)
TextField.backgroundColor = UIColor.whiteColor()
TextField.textAlignment = .Center
TextField.font = UIFont(name: "Helvetica Neue", size: 23)
number.position = CGPoint(x: size.width * 0.5, y: size.height * 0.95)
addChild(number)
logo.position = CGPoint(x: size.width * 0.5, y: size.height * 0.72)
addChild(logo)
check.position = CGPointMake(size.width/2,size.height/2 - 43)
check.name = "checkbutton"
addChild(check)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(touchLocation)
if(touchedNode.name == "checkbutton"){
if(TextField.text == "auto"){
println("CORRECT")
}
} else {
}
}
}
Your var TextField is local to the method didMoveToView so cannot be accessed from inside touchesBegan. Move this var outside of didMoveToView into the class level.
Also, by convention vars should start with a lower case letter: textField rather than TextField.