Set <UITouch>? does not have a member named Generator - ios

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
}

Related

How to detect which one object i touched in sceneView at ARKitExample?

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")
}
}
}

Swift: Using switch statement in touchesBegan

I want to clean up my touchesBegan(..) in SKScene. I wanted to make a case statement instead of my if .. else chain. However, I get errors when implementing, which suggests that I don't know how equality is done under the hood.
Before code:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) === playLabel {
buildLevelSelect()
} else if self.nodeAtPoint(location) === aboutLabel {
createAboutView()
} else if self.nodeAtPoint(location) === storeLabel {
createStore()
}
}
}
After code: After clicking around, some label clicks work, but some others raise a Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode 0x0) error:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
switch(self.nodeAtPoint(location)){
case playLabel :
buildLevelSelect()
case aboutLabel :
createAboutView()
case storeLabel :
createStore()
default : break
}
}
You can write a sort of odd looking but functional switch if you want the === behavior as follows:
switch(true){
case self.nodeAtPoint(location) === playLabel : buildLevelSelect()
case self.nodeAtPoint(location) === aboutLabel : createAboutView()
case self.nodeAtPoint(location) === storeLabel : createStore()
default : break
}
In my opinion, this is still cleaner looking than the if-else chain.
The easiest way to accomplish this would be by populating the .name property of your nodes, so then you could switch on the name instead. So then your switch would look like this:
switch (self.nodeAtPoint(location).name ?? "") {
case "playLabel" :
buildLevelSelect()
case "aboutLabel" :
...
You can also cast the objects in the switch statement and then your code works as expected
if let touch = touches.first as UITouch! {
let touchLocation = touch.location(in: self)
switch self.atPoint(touchLocation) {
case redBox as SKSpriteNode:
print("touched redBox")
case greenBox as SKSpriteNode:
print("touched greenBox")
default:
print("touched nothing")
}
}

Initializer for conditional binding must have Optional type, not 'UITouch'

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 {}

'Set<NSObject>' does not have a member named 'anyObject." - Xcode 6.3

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)
}
}
}

False if Statement Still Executes

I am using the Xcode 6 Beta, and I have used this exact code in another class, setup up in the same way. For some reason it doesn't want to work here. When I touch an SKNode, I grab its name, and compare the name to two strings, if it matches either of them, I execute some code. See below.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let node: SKNode = self.nodeAtPoint(touch.locationInNode(self))
if node.name == "body" || "face" {
self.childNodeWithName("face").runAction(SKAction.rotateByAngle(6.283, duration: 0.75))
}
}
}
As I said before, this exact code work flawlessly everywhere else I have used it, but no matter which node I press, the code inside the if statement will be run. Yes, I have printed out the names of nodes I am touching, and they do not match. Any ideas?
You probably meant
if node.name == "body" || node.name == "face" {
It would be more clear with parentheses, you are doing:
if (node.name == "body") || ("face") {
And "face" is true, which probably is a bug on Apple's side as String does not conform to LogicValue so you should not be able to test it like that. Probably the literal gets interpreted as something else conforming to LogicValue e.g. a CString.
Your if is idiomatically expressed as a switch with
switch node.name {
case "body", "face":
self.childNodeWithName ...
default: break
}
I think it should
if node.name == "body" || node.name == "face" { //change this statement
replace this in your function
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
for touch: AnyObject in touches {
let node: SKNode = self.nodeAtPoint(touch.locationInNode(self))
if node.name == "body" || node.name == "face" { //change this statement
self.childNodeWithName("face").runAction(SKAction.rotateByAngle(6.283, duration: 0.75))
}
}
}

Resources