I'm checking to see if an element has been selected.
func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
{
// First, see if the game is in a paused state
if !gamePaused
{
// Declare the touched symbol and its location on the screen
let touch = touches.anyObject! as? UITouch
let location = touch.locationInNode(symbolsLayer)
And this had previously compiled fine in Xcode 6.2 but with a 6.3 update, the line "let touch = touches.anyObject! as? UITouch" is throwing the error:
'Set' does not have a member named 'anyObject'
I've read through many similar question, but I can't seem to wrap my head around "To use the value, you need to “unwrap” it first." Especially because the answers seem to focus on notifications.
Thank you so much.
W
let touch = touches.first as? UITouch
.first can allow you to access first object of UITouch.
Since Xcode 6.3 uses an updated version of Swift (1.2) you need to convert your old code into Swift 1.2 (Edit -> convert -> To lastest Swift).
Swift 1.2, uses Set’s (new in Swift) instead of using NSSet’s (old one in Objective-C). Thus the touchbegan function also changes its parameters from NSSet to Set.
For more info, refer this
This would check for multiple touches in symbolsLayer
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
{
// First, see if the game is in a paused state
if !gamePaused
{
// Declare the touched symbol and its location on the screen
for touch: AnyObject in touches {
let location = (touch as! UITouch).locationInNode(symbolsLayer)
}
}
}
Related
The simplified code below freezes when dictionary keys contain a period. The app doesn't crash, just ignores gestures and touches. For instance, the touchesBegan function in the UIViewController doesn't get called.
Replacing the period with another character like a dash allows the app to function.
Are Swift dictionaries not allowed to contain periods in keys?
let name = "TSC-Body.043" // App fails with this "name" definition
// let name = "TSC-Body-043" // App works with this "name" definition
var test = [String:Any]()
if test[name] == nil {
test[name] = UIColor.black
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("Never gets called with a period in keys")
}
in Apple's ARKitExample, if i add multiple virtual objects(two chair) in one scene view. How to detect which one chair i touched in sceneView at ARKitExample?
the sceneView.hitTest() function will return the array of SCNHitTestResult, but the result.node is kind class of SCNNode, i don't know the object i touched is which one chair?
Dose anyone could help this? Thanks a lots
You are respondsible for tracking which nodes belong to which objects. I usually use a Set since SCNNode is hashable. You can then easily test if the node belongs to one of the objects you are interested in:
guard let result = sceneView.hitTest(location, options: nil).first else {
return
}
if myObjectNodes.contains(result.node) { //myObjectNodes is declared as Set<SCNNode>
//This is a match
}
To elaborate on the answer from #JoshHomann, you can do something like this
Swift 4
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first as! UITouch
if(touch.view == self.sceneView){
print("touch working")
let viewTouchLocation:CGPoint = touch.location(in: sceneView)
guard let result = sceneView.hitTest(viewTouchLocation, options: nil).first else {
return
}
if myObjectNodes.contains(result.node) { //myObjectNodes is declared as Set<SCNNode>
print("match")
}
}
}
I know how to do shake gesture and how to find location separately, however I don't know how to find location after the user shakes the device. I have xcode version 6.4.
Right now I have a motion ended function. And a showUserLocation function.
I would like to put a statement in motionEnded that calls the showUserLocation so that the location is found if the user shakes the phone.
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
?????
}
// Showing the user location
func showUserLocation(sender : AnyObject) {
let status = CLLocationManager.authorizationStatus()
//Asking for authorization to display current location
if status == CLAuthorizationStatus.NotDetermined {
locationManager.requestWhenInUseAuthorization()
} else {
locationManager.startUpdatingLocation()
}
Your question has nothing to do with a shake motion ending or calling location. Your question is one of basic syntax of Swift and general understanding of any programming language.
You code implementation for getting a location was "boxed" into an action func, perhaps a UIButton touchup inside where a sender was required as an argument. But you do not use the sender at all for getting location information, so it is easy to move this implementation to its own function, showUserLocationHelper so the action func can call getLocation and the shake motion can call get location.
The name of your action function: showUserLocation is poorly named it should have a name like btnShowUserLocationTouchUpInside, a long name but not confusing like what you named your action function and than tried to use in motionEnded.
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
//you can't pass the sender so couldn't call your showUserLocation action function,
//so move implementation of showUserLocation to showUserLocationHelper and now you can do what you need after shake event
showUserLocationHelper()
}
// Showing the user location
//this is an action function for some UI element like a UIButton and the sender is required to be passed for this function to fire thus, motionEnded cannot directly call it
//but you do not use sender at all
func showUserLocation(sender : AnyObject) {
showUserLocationHelper()
}
func showUserLocationHelper() {
let status = CLLocationManager.authorizationStatus()
//Asking for authorization to display current location
if status == CLAuthorizationStatus.NotDetermined {
locationManager.requestWhenInUseAuthorization()
} else {
locationManager.startUpdatingLocation()
}
}
I am currently getting an error in this code block for a SpriteKit game. In the if let statement I am getting the following error.
Initializer for conditional binding must have Optional type, not
'UITouch'
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
StopSideMovement = false
if let touch = touches.first! as UITouch {
if touch.locationInView(self.view).x > screenWidth/2 {
MoveRight = true
} else if touch.locationInView(self.view).x < screenWidth/2 {
MoveLeft = true
}
}
}
Does anybody know how I can fix this issue? Thank you!
This line
if let touch = touches.first! as UITouch {
should be
if let touch = touches.first {
Why?
touches.first does return a UITouch?. But if you add this guy ! and write
touches.first!
then you are performing a force unwrap and you are getting (at compile time) a UITouch.
So the whole conditional unwrapping is no longer needed.
Of course you should avoid force unwrap an use safer statements (like the conditional unwrapping) unless your are absolutely sure there will be some value inside the Optional.
The type of the Set's contents are specified as being UITouch. So you don't need the downcast. you just need to unwrap it.
if let touch = touches.first {}
I find it hard to fix this error please who can help me
xcode 7 beta 2
Set UITouch ? does not have a member named Generator
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
for obj in touches {
if let touch = obj as? UITouch {
let view = self.touchToView[touch]
self.handleControl(view, controlEvent: .TouchCancel)
self.touchToView[touch] = nil
}
}
}
}
enter image description here
You need to unwrap the optional - try
for obj in touches! {
// code here
}