I have I think a stupid question for you, but I start Xcode just one week ago and I have a problem with a loop condition.
for index in 1...4 {
AvatarPlayer1.layer.borderWidth = 4
AvatarPlayer1.layer.cornerRadius = 8
AvatarPlayer1.layer.borderColor = UIColor.white.cgColor
AvatarPlayer1.layer.masksToBounds = false
AvatarPlayer1.clipsToBounds = true //Mask for picture
}
How can I change the 1 value by for number in the loop.
I have try + , + \(index), + index.
You cannot change a variable name in code. Instead, start with an array of your four AvatarPlayer objects and cycle through the array:
let myArrayOfAvatarPlayers = [AvatarPlayer1, AvatarPlayer2, AvatarPlayer3, AvatarPlayer4]
for thisPlayer in myArrayOfAvatarPlayers {
thisPlayer.layer.borderWidth = 4
thisPlayer.layer.cornerRadius = 8
thisPlayer.layer.borderColor = UIColor.white.cgColor
thisPlayer.layer.masksToBounds = false
thisPlayer.clipsToBounds = true //Mask for picture
}
In addition to matt's answer, you could move the setup up stuff to the object init or setup method.
After that, you could use init(repeating:count:) for the list's init. See: https://developer.apple.com/documentation/swift/array/1641692-init
Related
I have an ARKit app that runs fine on iOS 12.x. On iOS 13 I encounter the following error in the console log:
[SceneKit] Error: Purging never freed texture <AGXA9FamilyTexture: 0x11d688240>
label = <none>
textureType = MTLTextureType2D
pixelFormat = MTLPixelFormatR16Float
width = 240
height = 1
depth = 1
arrayLength = 1
mipmapLevelCount = 1
sampleCount = 1
cpuCacheMode = MTLCPUCacheModeDefaultCache
storageMode = MTLStorageModePrivate
hazardTrackingMode = MTLHazardTrackingModeTracked
resourceOptions = MTLResourceCPUCacheModeDefaultCache MTLResourceStorageModePrivate MTLResourceHazardTrackingModeTracked
usage = MTLTextureUsageShaderRead MTLTextureUsageShaderWrite
shareable = 0
framebufferOnly = 0
purgeableState = MTLPurgeableStateNonVolatile
swizzle = [MTLTextureSwizzleRed, MTLTextureSwizzleGreen, MTLTextureSwizzleBlue, MTLTextureSwizzleAlpha]
isCompressed = 0
parentTexture = <null>
parentRelativeLevel = 0
parentRelativeSlice = 0
buffer = <null>
bufferOffset = 512
bufferBytesPerRow = 0
allowGPUOptimizedContents = YES
label = <none>
It repeats every few milliseconds and clutters the whole log. I was not able to narrow down where it comes from.
The interesting part is, that this even occurs when not a single node is present in the scene. If I remove the entire sceneView from the view then it disappears...(not an option)
Anybody any idea or hint how to track this down ?
Thanks
I fixed this issue by updating the setting of the scene camera:
var sceneView: ARSCNView!
...
sceneView.pointOfView?.camera?.wantsHDR = false
Hope this helps.
I have found the problem code line. In iOS 13 any call to
SceneView.snapshot()
produces that error. The apple docs say:
This method is thread-safe and may be called at any time.
but this seems to have changed in iOS13. I will file a bug report not hoping for a fast solution ;-)
I am trying to implement this code which I got from an apple WWDC video. However the video is from 2016 and I think the syntax has changed. How do I call sizeof(Float)? This produces an error.
func render(buffer:AudioBuffer){
let nFrames = Int(buffer.mDataByteSize) / sizeof(Float)
var ptr = UnsafeMutableRawPointer(buffer.mData)
var j = self.counter
let cycleLength = self.sampleRate / self.frequency
let halfCycleLength = cycleLength / 2
let amp = self.amplitude, minusAmp = -amp
for _ in 0..<nFrames{
if j < halfCycleLength{
ptr.pointee = amp
} else {
ptr.pointee = minusAmp
}
ptr = ptr.successor()
j += 1.0
if j > cycleLength {
}
}
self.counter = j
}
The sizeof() function is no longer supported in Swift.
As Leo Dabus said in his comment, you want MemoryLayout<Type>.size, or in your case, MemoryLayout<Float>.size.
Note that tells you the abstract size of an item of that type. However, due to alignment, you should not assume that structs containing different types of items will be the sums of the sizes of the other elements. Also, you need to consider the device it's running on. On a 64 bit device, Int is 8 bytes. On a 32 bit device, it's 4 bytes.
See the article on MemoryLayout at SwiftDoc.org for more information.
I am using UserDefaults to save values to determine when to present an interstitial ad within my application.
Here is the code used to increment the numbers:
if((defaults.integer(forKey: PRESENT_INTERSTITIAL_NUMBER) > defaults.integer(forKey: CURRENT_INTERSTITIAL_NUMBER))){
print("1111")
let oldNumber = defaults.integer(forKey: CURRENT_INTERSTITIAL_NUMBER)
let newNumber = oldNumber + 1
defaults.set(newNumber, forKey: CURRENT_INTERSTITIAL_NUMBER)
print("oldNumber \(oldNumber)")
print("newNumber \(newNumber)")
print("INTER NUMBER \(defaults.integer(forKey: CURRENT_INTERSTITIAL_NUMBER))")
print(defaults.integer(forKey: PRESENT_INTERSTITIAL_NUMBER))
}
I declare user defaults as follows let defaults = UserDefaults.standard
My problem is that is it doesn't always increment the values correctly. I have toyed with this for about an hour to try and work it out.
CASE 1:
CURRENT_INTERSTITIAL_NUMBER = 0
PRESENT_INTERSTITIAL_NUMBER = 4
... run incrementing code ...
CURRENT_INTERSTITIAL_NUMBER = 1
PRESENT_INTERSTITIAL_NUMBER = 4
... run incrementing code ...
CURRENT_INTERSTITIAL_NUMBER = 1
PRESENT_INTERSTITIAL_NUMBER = 4
... run incrementing code ...
CURRENT_INTERSTITIAL_NUMBER = 1
PRESENT_INTERSTITIAL_NUMBER = 4
... run incrementing code ...
CURRENT_INTERSTITIAL_NUMBER = 2
PRESENT_INTERSTITIAL_NUMBER = 4
It appears to be random when the value doesn't properly carry over, but I can't figure out why it is doing this.
Thanks!
I'm back again with what is likely a simple issue, however its got me stumped.
I've written very small, very basic piece of code in an xcode playground.
My code simply iterates over a function 10 times, printing the output each time.
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
}
Now for my issue, It seems my code properly increments the 'start' variable.... running and printing 10 times. However it prints out a list of 0's. For some reason the 'x' variable isn't incrementing.
I've consulted the few ebooks I have for swift, aswell as the documentation, and as far as i can see my code should work.
Any ideas?
P.s. As per the documentation I have also tried ++x, to no avail.
edit
Updated, working code thanks to answers below:
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print("The variable is", x, "and doubled it is", answer)
}
while start <= 10 {
spin()
x++
start++
answer = 2 * x
}
You have just assigned 2 * x to answer at the beginning of the program, when x == 0, and the value of answer remains its initial value through out the program. That's how Value Types work in Swift as well as in almost any other languages
If you wish to always have answer to be 2 times of x, you should write like this
var start = 0
var x = 0
var answer = 2 * x
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
answer = 2 * x
}
And thanks to Leo Dabus's answer, you may also define a Computed Property to caculate the value of 2 * x each time you try to get the value of answer. In this way, answer becomes readonly and you cannot assign other values to it. And each time you try to get the value of answer, it performs the 2 * x calculation.
var start = 0
var x = 0
var answer: Int {
return 2 * x
}
func spin() {
print(answer)
}
while start < 10 {
spin()
x++
start++
}
What you need is a read only computed property. Try like this:
var answer: Int { return 2 * x }
I want to be able to change a node's physicsBody height when the user swipes downwards, but have not been able to find out how to do this, beside resetting the entire physicsBody.
When I originally load the node, I use the below code:
nodeHero.color = UIColor .grayColor()
nodeHero.size.width = 20
nodeHero.size.height = 45
nodeHero.position.x = -frame.size.width/2 + 45
nodeHero.position.y = pointMainY + 30 + nodeHero.size.height/2
nodeHero.zPosition = 110
nodeHero.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(nodeHero.size.width, nodeHero.size.height))
nodeHero.physicsBody?.mass = 1
nodeHero.physicsBody?.angularVelocity = 0
nodeHero.physicsBody?.allowsRotation = false
nodeHero.physicsBody?.restitution = 0
nodeHero.physicsBody?.categoryBitMask = bitHero
addChild(nodeHero)
And when I swipe down, I want to be able to do something like this (this doesn't work):
nodeHero.size.height = 28
nodeHero.physicsBody?.size.height = 28
But instead I have to use the nodeHero.physicsBody = SKPhysicsBody() again, which resets all the other physicsBody properties, so I have to do this:
nodeHero.size.height = 28
nodeHero.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(nodeHero.size.width, nodeHero.size.height))
nodeHero.physicsBody?.mass = 1
nodeHero.physicsBody?.angularVelocity = 0
nodeHero.physicsBody?.allowsRotation = false
nodeHero.physicsBody?.restitution = 0
nodeHero.physicsBody?.categoryBitMask = bitHero
According to SpriteKit documentation the area of a SKPhysicsBody can't be modified, so you need to create another SKPhysicsBody instance and copy the values you want to keep from the previous instance.