I am new to programming and new to this forum.. I have a problem with stack views. Once I had implemented stack views: https://i.stack.imgur.com/7Lgf0.png my code to dismiss keyboard stopped working. When I hit the text box the keyboard appears and I can enter values. When clicking outside the text box the keyboard remains. Without Stack views all is well.. Here is the code for dismiss keyboard:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
}
// dismiss keyboard on touch outside textfield
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for txt in self.view.subviews {
if txt.isKind(of: UITextField.self) && txt.isFirstResponder {
txt.resignFirstResponder()
}
}
}
What am I doing wrong?? how do I get the keyboard dismiss function to work again while keeping stack views?
Try to remove everything in the touchesBegan function and just add self.view.endEditing(true) in it. I tried this with my textfield in UIStackView and this line does it all.
Swift 4.1:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
I am having trouble with detecting a specific node being touched. Here is what i have to far.
let playagain = SKSpriteNode(imageNamed: "PlayAgain.png")
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
}
then when the player dies these two nodes come up.
playagain.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.5)
addChild(playagain)
gameover.position = CGPoint(x:frame.size.width * 0.5, y: frame.size.height * 0.75)
addChild(gameover)
everything above works. the node comes on the screen where i asked i just can't seem to get it to show i clicked it.
as you can see the node is called playagain, when the playagain node is clicked i want to be able to refresh the game. what i have so far is below.
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in touches {
let location = (touch as! UITouch).locationInNode(self)
let play = self.nodeAtPoint(location)
if play.name == "playagain" {
println("touched")
}
}
}
thanks!
Are you not using the latest Xcode? Your touches began code should not run with swift 2 and Xcode 7.
Try this
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
if playagain.containsPoint(location) {
/// playagain was pressed, do something
}
}
}
or this
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(location)
if touchedNode == playagain {
/// playagain was pressed, do something
}
}
}
How would I go about moving an object to follow touch in the newest version of swift. So if you touch the object it will follow your finger around until you remove your finger.
You should use the touchesBegan and touchesMoved methods.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
thing.center = (touch.locationInView(self.view))
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
thing.center = touch.locationInView(self.view)
}
}
For more info, watch this video. Hope this helps.
Xcode 6.3. Within a class implementing UITextFieldDelegate protocol, I would like to override touchesBegan() method to possibly hide the keyboard. If I avoid a compiler error in the function spec, then there is a complier error trying to read the "touch" from the Set or NSSet, or else the super.touchesBegan(touches , withEvent:event) throws an error. One of these combinations compiled in Xcode 6.2! (So where is documentation to Swift "Set" and how to get an element from one?)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
// Hiding the Keyboard when the User Taps the Background
if let touch = touches.anyObject() as? UITouch {
if nameTF.isFirstResponder() && touch.view != nameTF {
nameTF.resignFirstResponder();
}
}
super.touchesBegan(touches , withEvent:event)
}
Try:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) or
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
Compiler error:
Overriding method with selector 'touchesBegan:withEvent:' has incompatible type '(NSSet, UIEvent) -> ()'
and
super.touchesBegan(touches , withEvent:event)
also complains
'NSSet' is not implicitly convertible to 'Set'; did you mean to use 'as' to explicitly convert?
Try:
override func touchesBegan(touches: Set<AnyObject>, withEvent event: UIEvent)
Compiler error:
Type 'AnyObject' does not conform to protocol 'Hashable'
Try:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
Compiler error at
if let touch = touches.anyObject() as? UITouch
'Set' does not have a member named 'anyObject' BUT the function spec and call to super() are OK!
Try:
override func touchesBegan(touches: NSSet<AnyObject>, withEvent event: UIEvent) -> () or
override func touchesBegan(touches: NSSet<NSObject>, withEvent event: UIEvent)
Compiler error:
Cannot specialize non-generic type 'NSSet'
Swift 1.2 (Xcode 6.3) introduced a native Set type that bridges
with NSSet. This is mentioned in the Swift blog and in the
Xcode 6.3 release notes, but apparently not yet added to the official documentation (update: As Ahmad Ghadiri noted, it is documented now).
The UIResponder method is now declared as
func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
and you can override it like this:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
// ...
}
super.touchesBegan(touches , withEvent:event)
}
Update for Swift 2 (Xcode 7): (Compare Override func error in Swift 2)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
// ...
}
super.touchesBegan(touches, withEvent:event)
}
Update for Swift 3:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
// ...
}
super.touchesBegan(touches, with: event)
}
With xCode 7 and swift 2.0, use following code:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
print("\(touch)")
}
super.touchesBegan(touches, withEvent: event)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
print("\(touch)")
}
super.touchesEnded(touches, withEvent: event)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
print("\(touch)")
}
super.touchesMoved(touches, withEvent: event)
}
Using Swift 3 and Xcode 8
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
// Don't forget to add "?" after Set<UITouch>
}
It is now in the Apple API reference here and for overriding in xCode version 6.3 and swift 1.2 you can use this code:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
// ...
}
// ...
}
The current one right now for the newest update as of xCode 7.2 Swift 2.1 on Dec 19, 2015.
Next time you get an error like this again, remove the function and start typing it again "touchesBe..." and xCode should automatically complete it to the newest one for you instead of trying to fix the old one.
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject! in touches {
let touchLocation = touch.locationInNode(self)
//Use touchLocation for example: button.containsPoint(touchLocation) meaning the user has pressed the button.
}
}
What worked for me was:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
// ...
}
super.touchesBegan(touches , withEvent:event!)
}
Small addition. For swift to compile w/o error, you need to add
import UIKit.UIGestureRecognizerSubclass
Using Swift 4 and Xcode 9
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first as? UITouch {
if touch.view == self.view{
self.dismiss(animated: true, completion: nil)
}
}
}
I have a game where i touch a node and it runs some code. How do I change the SKShapeNode's color when touched? I tried to use node.fillColor = SKColor.blackcolor() for example but it says that I cannot do that even though thats how i originally created the SKShapeNode's color in the first place.
This is all writing within touches began method.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let positionOfTouch = touch.locationInNode(self)
let node = nodeAtPoint(positionOfTouch)
node.userInteractionEnabled = true
node.fillColor = UIColor.whiteColor()
This is the code I am using. But it keeps saying "Value of type SKNode has no member "fillColor"...But "fillColor" works in my DidMoveToView.
Thanks
The node you are likely to touch may be a parent or child node - an SKNode, not an SKShapeNode. That's what nodeAtPoint returns, and a generic SKNode doesn't have a fillColor. You need to check it is the class you are expecting by testing. Something like...
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let positionOfTouch = touch.locationInNode(self)
if let node = nodeAtPoint(positionOfTouch) as? SKShapeNode {
node.userInteractionEnabled = true
node.fillColor = UIColor.whiteColor()