SKSpriteNode Won't Move - xcode

I have created a rectangular image in the form of an SKSpriteNode in Swift with the following code:
var screenImage = SKSpriteNode(texture: SKTexture(imageNamed: "\(imageChoices[randomImageChoice].0)"))
screenImage.position = CGPointMake(screen1.position.x, screen1.position.y)
screenImage.size = CGSizeMake(self.frame.size.width * 0.6, self.frame.size.height)
self.addChild(screenImage)
I proceed to move the image with the following code:
func swipedTrue(sender: UISwipeGestureRecognizer) {
if gameOver == false && tutorial == false {
//if you swipe, it checks if you were right, then moves on or GameOver()
if (wordChoices[randomWordChoice]).1 == true {
//reset time
timePerQuestion = 1.0
//randomize word
randomWordChoice = Int(arc4random() % 3)
newImage = SKSpriteNode(texture: SKTexture(imageNamed: "\(wordChoices[randomWordChoice].0)"))
//randomize color of screens, mid-swipe
newScreen.fillColor = UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
//replace timeBar
decreaseTimeBlock.fillColor = newScreen.fillColor
decreaseTimeBlock.position = CGPointMake(self.frame.size.width * 1.5, self.frame.size.height * 0.985)
timeBarRedValue = 0.0; timeBarGreenValue = 1.0
newTimeBar.fillColor = UIColor(red: CGFloat(timeBarRedValue), green: CGFloat(timeBarGreenValue), blue: 0.0, alpha: 1.0)
//actions caused by swipe: it's "bringNewScreen" because if you swipeFalse, the newScreen comes from bottom. If you swipeTrue, it comes from the top.
var swipeTrueCurrentScreen = SKAction.moveToX(self.frame.size.width * 2, duration: 0.5)
var bringNewScreen = SKAction.moveToY(self.frame.size.height * 0.5, duration: 0.5)
var bringNewTimeBar = SKAction.moveToY(self.frame.size.height * 0.985, duration: 0.5)
//reset the newScreen and word to the top of the screen, to be dropped again
newScreen.position = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 1)
newImage.position = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 1)
newTimeBar.position = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 1.58)
//swipe word and screen
currentImage.runAction(swipeTrueCurrentScreen)
currentTimeBar.runAction(swipeTrueCurrentScreen)
currentScreen.runAction(swipeTrueCurrentScreen)
//make swiping noise
runAction(SKAction.playSoundFileNamed("Swoosh 3-SoundBible.com-1573211927.mp3", waitForCompletion: false))
//bring in the newScreen
newScreen.runAction(bringNewScreen)
newImage.runAction(bringNewScreen)
newTimeBar.runAction(bringNewTimeBar)
//increase score
++score
scoreLabel.text = "\(score)"
//here, switch the currentScreen with the newScreen so that the process can be repeated
if newScreen == screen1 {
newScreen = screen2
newImage = screenImage2
newTimeBar = timeBar2
currentScreen = screen1
currentImage = screenImage1
currentTimeBar = timeBar1
} else {
newScreen = screen1
newImage = screenImage1
newTimeBar = timeBar1
currentScreen = screen2
currentImage = screenImage2
currentTimeBar = timeBar2
}
} else {
GameOver()
}
}
}
However, for some reason, the image will not move, and when I try to move it in other situations at well, it refuses. How can I fix this?

Except one missing parenthesis here (but I guess it's not the case in your code) the code have no particular reason to not work. The problem is most likely on how you use it.
My guess is that you are doing something like so :
import SpriteKit
class GameScene: SKScene {
var sprite : SKSpriteNode = SKSpriteNode() // A
override func didMoveToView(view: SKView) {
// You are creating another `sprite` variable
// and not using the (A) sprite you declare above
var sprite = SKSpriteNode(imageNamed:"Spaceship") // B
// Here you set the (B) sprite you just created
sprite.size = CGSizeMake(self.frame.size.width * 0.6, self.frame.size.height)
sprite.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
// Here it's still the (B) sprite you just created
// that you add to the scene
self.addChild(sprite)
// You are calling your action from somewhere else
self.applyAction()
}
func applyAction() {
// You create an action, OK
let action = SKAction.moveToX(self.frame.size.width * 2, duration: 0.5)
// You apply the action to the (A) sprite property you have in your class
// Same as : self.sprite.runAction(action)
sprite.runAction(action)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
In that case, you just have to not create another sprite variable. By removing the var keyword on the // B line.
Let met know if it helped.
If it's not the case, please give more details (code, ...).

Related

error removing child node from parent node in spriteKit Swift4

I made a parallax background, in GameScene.sks I added an empty node, added two sprites to an empty node. I have a reset button, when I click on it I need the background to be removed and added to its position (restarted), but when I add in scrollBg.removeAllChildren restart function I error occurs, how do I properly add and remove children from the scene ?
import SpriteKit
import GameplayKit
class GameScene: SKScene {
var player: SKSpriteNode!
var scrollBg: SKNode!
var spawnTimer: CFTimeInterval = 0
let fixedDelta: CFTimeInterval = 1.0/60.0 /* 60 FPS */
let scrollSpeed: CGFloat = 700
var sinceTouch: CFTimeInterval = 0
func resetGameScene() {
scrollBG.removeAllChildren()
player.removeAllChildren()
player.position = CGPoint(x: 590 , y: 690)
pauseButton()
}
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
player = childNode(withName: "player") as? SKSpriteNode
scrollBg = childNode(withName: "scrollBG")!
resetGameScene()
}
func scrollWorld() {
scrollBg.position.y -= scrollSpeed * CGFloat(fixedDelta)
for ground in scrollBg.children as! [SKSpriteNode] {
let groundPosition = scrollBg.convert(ground.position, to:
self)
if groundPosition.y <= -ground.size.width {
let newPosition = CGPoint(x: groundPosition.x, y:
(self.size.width ) + ground.size.width * 2)
ground.position = self.convert(newPosition, to:
scrollBg)
}
}
}
override func update(_ currentTime: TimeInterval) {
sinceTouch+=fixedDelta
spawnTimer+=fixedDelta
scrollWorld()
}
}

Shaders.metal only get the y value of the mouse

I want to use mouse to control camera position computed by compute function. in my view code:
import MetalKit
public class MetalView: MTKView, NSWindowDelegate {
var queue: MTLCommandQueue! = nil
var cps: MTLComputePipelineState! = nil
var timer: Float = 0
var timerBuffer: MTLBuffer!
var mouseBuffer: MTLBuffer!
var pos: NSPoint!
required public init(coder: NSCoder) {
super.init(coder: coder)
self.framebufferOnly = false
device = MTLCreateSystemDefaultDevice()
registerShaders()
}
override public func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
if let drawable = currentDrawable {
let command_buffer = queue.commandBuffer()
let command_encoder = command_buffer.computeCommandEncoder()
command_encoder.setComputePipelineState(cps)
command_encoder.setTexture(drawable.texture, atIndex: 0)
command_encoder.setBuffer(timerBuffer, offset: 0, atIndex: 1)
command_encoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2)
update()
let threadGroupCount = MTLSizeMake(8, 8, 1)
let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1)
command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
command_encoder.endEncoding()
command_buffer.presentDrawable(drawable)
command_buffer.commit()
}
}
func registerShaders() {
queue = device!.newCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.newFunctionWithName("compute")!
timerBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: [])
cps = try device!.newComputePipelineStateWithFunction(kernel)
} catch let e {
Swift.print("\(e)")
}
}
func update() {
timer += 0.01
var bufferPointer = timerBuffer.contents()
memcpy(bufferPointer, &timer, sizeof(Float))
bufferPointer = mouseBuffer.contents()
memcpy(bufferPointer, &pos, sizeof(NSPoint))
}
override public func mouseDragged(event: NSEvent) {
pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil))
let scale = layer!.contentsScale
pos.x *= scale
pos.y *= scale
debugPrint("Hello",pos.x,pos.y)
}
}
and my shader code:
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
constant float &timer [[buffer(1)]],
constant float2 &mouse [[buffer(2)]],
uint2 gid [[thread_position_in_grid]])
{
int width = output.get_width();
int height = output.get_height();
float2 uv = float2(gid) / float2(width, height);
uv = uv * 2.0 - 1.0;
// scale proportionately.
if(width > height) uv.x *= float(width)/float(height);
if(width < height) uv.y *= float(height)/float(width);
float2 mpos = mouse * 2.0 - 1.0;
float3 cameraPosition = float3( mpos.x,mpos.y, -10.0 );///<-- mouse position to set camera position
...
}
But somehow I only get the mpos.y value. It seems like mpos.x is not send over to the compute function. How can I resolve this?
NSPoint's fields are CGFloat. I think the issue is that, for 64-bit, CGFloat is defined as Double, not Float. Metal's float corresponds to Swift's Float, not Double. Presumably, float2 corresponds to two Swift Floats. Your buffer layout is wrong. Copy two Floats, not an NSPoint, into mouseBuffer.

SKSpriteNode not able to have multiple children

I'm trying to have multiple sprite nodes of the same type/parent, but when I try to spawn another node I get an error. 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent'
Here's my code:
import SpriteKit
class GameScene: SKScene {
//global declarations
let player = SKSpriteNode(imageNamed: "mage")
let fireball = SKSpriteNode(imageNamed: "fireball")
override func didMoveToView(view: SKView) {
/* Setup your scene here */
createScene()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch in (touches as! Set<UITouch>) {
let location = touch.locationInNode(self)
spawnFireball(location)
}
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
self.enumerateChildNodesWithName("fireball", usingBlock: ({
(node,error) in
if (self.fireball.position.x < -self.fireball.size.width/2.0 || self.fireball.position.x > self.size.width+self.fireball.size.width/2.0
|| self.fireball.position.y < -self.fireball.size.height/2.0 || self.fireball.position.y > self.size.height+self.fireball.size.height/2.0) {
self.fireball.removeFromParent()
self.fireball.removeAllChildren()
self.fireball.removeAllActions()
}
}))
}
func createScene() {
//player
player.size = CGSizeMake(100, 100)
player.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2 + 50)
player.zPosition = 2.0
self.addChild(player)
}
func spawnFireball(point: CGPoint) {
//setup
fireball.name = "fireball"
fireball.size = CGSizeMake(100, 50)
let fireballCenter = CGPointMake(fireball.size.width / 4 * 3, fireball.size.height / 2)
fireball.position = player.position
fireball.physicsBody = SKPhysicsBody(circleOfRadius: fireball.size.height/2, center: fireballCenter)
fireball.physicsBody?.affectedByGravity = false
//action
var dx = CGFloat(point.x - player.position.x)
var dy = CGFloat(point.y - player.position.y)
let magnitude = sqrt(dx * dx + dy * dy)
dx /= magnitude
dy /= magnitude
let vector = CGVector(dx: 32.0 * dx, dy: 32.0 * dy)
var rad = atan2(dy,dx)
fireball.runAction(SKAction.rotateToAngle(rad, duration: 0.0))
self.addChild(fireball)
fireball.physicsBody?.applyImpulse(vector)
}
}
You need to instantiate another SKSpriteNode. In your existing code, you create a single fireball and add it to the scene; your program crashes when you try to add the same fireball again.
First, remove your let fireball = SKSpriteNode... line. Move it to inside the spawnFireball() method, like so:
func spawnFireball(point: CGPoint) {
let fireball = SKSpriteNode(imageNamed: "fireball")
//Insert all customization here (your existing code should mostly work)
self.addChild(fireball)
}
Because the fireball variable is a local variable, you can now instantiate a new one every time you call the function. Now, just change your update() method to properly use enumerateChildrenWithName() by getting changing every self.fireball to just node.
This way, the code will loop through every existing fireball that is currently on the scene, rather than your current code, which only allows you to create one fireball.

Do I have to delete a sprite node once I end up using it?

I'm creating a series of moving pipes in my scene. But it always crashes after ~30 pipes are generated. Is it because of too many nodes in the scene and no memories for new ones? The code is like this:
import SpriteKit
class GameScene: SKScene {
var mainPipe: SKSpriteNode = SKSpriteNode()
var space:Float = 1000
var pipeCount:Int = 0
override func didMoveToView(view: SKView) {
self.backgroundColor = SKColor.blackColor()
self.size.width = 640
self.size.height = 1136
}
func randomOffset() -> Float{
var rNum:Float = Float(arc4random()%181) // 0-180
return rNum
}
var durations: CFloat = 5.0
var colorPipes:UIColor = UIColor.grayColor()
func spawnPipeRow(offs:Float){
self.pipeCount = self.pipeCount + 1
println("\(self.pipeCount)")
//offs is the random number
//let offset = offs + (space/2) - 105
let offset = offs + Float(self.size.height/100) - 180
// mainPipe = SKSpriteNode(color:colorPipes, size:CGSize(width: view.bounds.size.width/3, height:700))
mainPipe = SKSpriteNode(color:colorPipes, size:CGSize(width: self.size.width/5, height:self.size.height/1.5))
let pipeBottom = (mainPipe as SKSpriteNode).copy() as SKSpriteNode
let pipeTop = (mainPipe as SKSpriteNode).copy() as SKSpriteNode
let xx = self.size.width * 2.0
self.setPositionRelativeBot(pipeBottom, x:Float(xx), y: offset )
self.setPositionRelativeTop(pipeTop, x:Float(xx), y: offset + space)
pipeBottom.physicsBody = SKPhysicsBody(rectangleOfSize: pipeBottom.size)
pipeTop.physicsBody = SKPhysicsBody(rectangleOfSize: pipeTop.size)
pipeBottom.physicsBody?.dynamic = false
pipeTop.physicsBody?.dynamic = false
//pipeTop.physicsBody?.contactTestBitMask = birdCategory
//pipeBottom.physicsBody?.contactTestBitMask = birdCategory
self.addChild(pipeBottom)
self.addChild(pipeTop)
var actionArray1:NSMutableArray = NSMutableArray()
actionArray1.addObject(SKAction.moveTo(CGPointMake(-1000, pipeBottom.size.height - 200), duration: NSTimeInterval(durations)))
var actionArray2:NSMutableArray = NSMutableArray()
actionArray2.addObject(SKAction.moveTo(CGPointMake(-1000, pipeTop.size.height - 200), duration: NSTimeInterval(durations)))
actionArray1.addObject(SKAction.removeFromParent())
actionArray2.addObject(SKAction.removeFromParent())
pipeBottom.runAction(SKAction.sequence(actionArray1))
pipeTop.runAction(SKAction.sequence(actionArray2))
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
for touch: AnyObject in touches {
}
}
override func update(currentTime: CFTimeInterval) {
var timeSinceLastUpdate = currentTime - lastUpdateTimerInterval
lastUpdateTimerInterval = currentTime
if(timeSinceLastUpdate > 1){
timeSinceLastUpdate = 1/60
lastUpdateTimerInterval=currentTime
}
updateWithTimeSinceLastUpdate(timeSinceLastUpdate)
/* Called before each frame is rendered */
}
func setPositionRelativeBot(node:SKSpriteNode, x: Float, y: Float){
let xx = (Float(node.size.width)/2) + x
let yy = (Float(self.size.height)/2) - (Float(node.size.height)/2) + y
node.position.x = CGFloat(xx)
node.position.y = CGFloat(yy)
}
func setPositionRelativeTop(node:SKSpriteNode, x:Float, y:Float){
let xx = (Float(node.size.width)/2) + x
let yy = (Float(self.size.height)/2) + (Float(node.size.height)/2) + y
node.position.x = CGFloat(xx)
node.position.y = CGFloat(yy)
}
var lastUpdateTimerInterval:NSTimeInterval = NSTimeInterval()
var lastYieldTimeInterval:NSTimeInterval = NSTimeInterval()
var speedOfBird: CDouble = 1.8
func updateWithTimeSinceLastUpdate(timeSinceLastUpdate:CFTimeInterval){
lastYieldTimeInterval += timeSinceLastUpdate
if(lastYieldTimeInterval > speedOfBird ){
lastYieldTimeInterval=0
self.spawnPipeRow(self.randomOffset())
if speedOfBird > 0.8{
speedOfBird -= 0.1}
}
}
}
You should remove your sprites from the scene when you no longer need them. However your problem is probably not related to the memory occupied by your textures:
SpriteKit Programming Guide
An SKTexture object is created and attached to the sprite. This
texture object automatically loads the texture data whenever the
sprite node is in the scene, is visible, and is necessary for
rendering the scene. Later, if the sprite is removed from the scene or
is no longer visible, Sprite Kit can delete the texture data if it
needs that memory for other purposes. This automatic memory management
simplifies but does not eliminate the work you need to do to manage
art assets in your game.
The texture object itself is just a placeholder for the actual texture
data. The texture data is more resource intensive, so Sprite Kit loads
it into memory only when needed.
If you already have an SKTexture object, you can create new textures
that reference a portion of it. This approach is efficient because the
new texture objects reference the same texture data in memory.
Try to delete them with this code :
override func update(currentTime: CFTimeInterval) {
self.enumerateChildNodesWithName("nodeName") {
node, stop in
if (node is SKSpriteNode) {
let sprite = node as SKSpriteNode
// Check if the node is not in the scene
if (sprite.position.x < -sprite.size.width/2.0 || sprite.position.x > self.size.width+sprite.size.width/2.0
|| sprite.position.y < -sprite.size.height/2.0 || sprite.position.y > self.size.height+sprite.size.height/2.0) {
sprite.removeFromParent()
println("outside")
}
}
}
}
Don't forget to named your node :
node.name = "nodeName"
Hope your crash will stop

Xcode Stopped Recognizing Global Variables - Swift

I've been working on an app for over a month and have many variables defined at the top of the Swift document that came with my tabbed interface template in XCODE. I've declared various UIColors to be used globally and have made a few classes where I draw a few different icon shapes. All of a sudden today Xcode is throwing up red errors of "Use of unresolved identifier [one of my UIColor variabls]" for all of my colors used throughout my drawing classes. I've tried to clean the project and restart Xcode Any idea what could be going on?
Here are my global variables:
import Foundation
import UIKit
import QuartzCore
//----Global Variables----
var timerMode = "start"
var arrowButtonTapped = false
var timerButtonTouched = false
var currentView = "brew it"
//--------My Colors -----------
let colorGreen = UIColor(red: 0.310, green: 0.725, blue: 0.624, alpha: 1.000)
let colorLightGreen = UIColor(red: 211/255, green: 217/255, blue: 195/255, alpha: 100)
var colorRed = UIColor(red: 241/255, green: 93/255, blue: 79/255, alpha: 100)
let colorDarkBlue = UIColor(red: 27/255, green: 29/255, blue: 38/255, alpha: 1.0)
let colorOrange = UIColor(red: 241/255, green: 162/255, blue: 128/255, alpha: 1.0)
let colorTransparent = UIColor(red: 241/255, green: 162/255, blue: 128/255, alpha: 0.0)
//----Countdown times----
var countTime : NSTimeInterval = 6
var halfCountTime : NSTimeInterval = countTime * 0.5
var okCountTime : NSTimeInterval = 2
//---- End Global Variables ----
//let cup1Graphic = coffeeMugVector()
//let cup2Graphic = coffeeMugVector()
//let cup3Graphic = coffeeMugVector()
//let cup4Graphic = coffeeMugVector()
//let cup5Graphic = coffeeMugVector()
//let cup6Graphic = coffeeMugVector()
//Coffe Cups x Coffee Strength returns amount of coffee as an integer
class coffeeCalculator {
var selectedCups = 0
var cupSelect = false
let coffeeStronger = 20
var coffeeStrength = 15
let coffeeWeaker = 15
var water = 226
//var cupAnimation = CSAnimationView(type:"morph", duration:0.5, delay:0)
// What to do when a cup is selected
func cupSelected() {
if cupSelect == true{
selectedCups++
}
else if selectedCups > 0{
selectedCups--
}
println("\(selectedCups)")
}
//take coffee cups multiplied by coffee strength and return the amount as a string
//Calcualte coffee and return an attributed string
func coffeeTextOnly() ->String {
var calculatedCoffee = selectedCups * coffeeStrength
var coffeeToString = "\(calculatedCoffee)"
return coffeeToString
}
func calculateCoffee() -> (NSMutableAttributedString) {
var calculatedCoffee = selectedCups * coffeeStrength
var coffeeToString = "\(calculatedCoffee)"
//Convert the CoffeeCalculator output to an attributed string
var coffeeText = NSMutableAttributedString(string:coffeeToString)
//Part 2 set the font attributes for the lower case g
var coffeeTypeFaceAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(18)]
//Part 3 create the "g" character and give it the attributes that you set up
var coffeeG = NSMutableAttributedString(string:"g", attributes:coffeeTypeFaceAttributes)
coffeeText.appendAttributedString(coffeeG)
return (coffeeText)
}
//Calculate teh amount of water needed and return it as a string
func calculateWater() -> (NSMutableAttributedString) {
var calculatedWater = water * selectedCups
var waterToString = "\(calculatedWater)"
var waterText = NSMutableAttributedString(string:waterToString)
//Part 2 set the font attributes for the lower case g
var waterTypeFaceAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(18)]
//Part 3 create the "g" character and give it the attributes that you set up
var waterG = NSMutableAttributedString(string:"g", attributes:waterTypeFaceAttributes)
waterText.appendAttributedString(waterG)
return (waterText)
}
}
////----BEGIN GRAPHICS ----////
//----Main Timer (circle) Button----//
#IBDesignable
class timerButtonGraphics: UIView {
override func drawRect(rect: CGRect) {
var bounds = self.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2
center.y = bounds.origin.y + bounds.size.height / 2
var radius = 31
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(Float(M_PI) * 2.0), clockwise: true)
path.strokeWithBlendMode(kCGBlendModeNormal, alpha: 0)
path.lineWidth = 1
if timerMode == "reset" || timerMode == "ok" {
colorRed.setStroke()
colorRed.setFill()
}
else {
colorGreen.setStroke()
colorGreen.setFill()
}
if timerButtonTouched == true {
path.lineWidth = 2
path.fill()
}
path.stroke()
}
}
//------Arrow Button------//
#IBDesignable
class arrowButtonGraphic: UIView {
override func drawRect(rect: CGRect) {
var bezierPath = UIBezierPath()
bezierPath.moveToPoint(CGPointMake(20.36, 2.68))
bezierPath.addLineToPoint(CGPointMake(2.69, 20.23))
bezierPath.addCurveToPoint(CGPointMake(2.69, 28.32), controlPoint1: CGPointMake(0.44, 22.46), controlPoint2: CGPointMake(0.44, 26.09))
bezierPath.addCurveToPoint(CGPointMake(10.84, 28.32), controlPoint1: CGPointMake(4.94, 30.56), controlPoint2: CGPointMake(8.59, 30.56))
bezierPath.addLineToPoint(CGPointMake(22.71, 16.53))
bezierPath.addCurveToPoint(CGPointMake(26.29, 16.53), controlPoint1: CGPointMake(23.7, 15.55), controlPoint2: CGPointMake(25.3, 15.56))
bezierPath.addLineToPoint(CGPointMake(38.16, 28.32))
bezierPath.addCurveToPoint(CGPointMake(46.31, 28.32), controlPoint1: CGPointMake(40.41, 30.56), controlPoint2: CGPointMake(44.06, 30.56))
bezierPath.addCurveToPoint(CGPointMake(46.31, 20.23), controlPoint1: CGPointMake(48.56, 26.09), controlPoint2: CGPointMake(48.56, 22.46))
bezierPath.addLineToPoint(CGPointMake(28.64, 2.68))
bezierPath.addCurveToPoint(CGPointMake(24.48, 1), controlPoint1: CGPointMake(27.49, 1.54), controlPoint2: CGPointMake(25.98, 0.98))
bezierPath.addCurveToPoint(CGPointMake(20.36, 2.68), controlPoint1: CGPointMake(22.99, 0.99), controlPoint2: CGPointMake(21.5, 1.55))
bezierPath.closePath()
bezierPath.miterLimit = 4;
colorGreen.setStroke()
bezierPath.lineWidth = 1
bezierPath.stroke()
colorGreen.setFill()
//Rotate arrow if on "weigh it" page
if arrowButtonTapped == true {
bezierPath.lineWidth = 2
bezierPath.stroke()
}
}
}
//----Timer Baground Circle ----//
#IBDesignable
class timerBackgroundCircle: UIView {
override func drawRect(rect: CGRect) {
var ovalPath = UIBezierPath(ovalInRect: CGRectMake(0, 0, 238, 238))
colorLightGreen.setFill()
ovalPath.fill()
}
}
//----Timer Bagkround Mask ----//
#IBDesignable
class timerMask: UIView {
override func drawRect(rect: CGRect) {
let colorGreen = UIColor(red: 0.310, green: 0.725, blue: 0.624, alpha: 1.000)
let colorRed = UIColor(red: 241/255, green: 93/255, blue: 79/255, alpha: 100)
let colorLightGreen = UIColor(red: 211/255, green: 217/255, blue: 195/255, alpha: 100)
//The shape to mask out
/*var ovalPath = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 238, height: 238))
colorGreen.setFill()
ovalPath.fill()*/
//The rectangle
var bounds : CGRect = self.bounds
var maskRect = CAShapeLayer()
maskRect.frame = bounds
//maskRect.fillColor = colorLightGreen.CGColor
//The circle mask
var maskCirclePath = UIBezierPath(ovalInRect: CGRect(x: 40, y: 150, width: 238, height: 238))
maskCirclePath.appendPath(UIBezierPath(rect: bounds))
//combine appended path to rectangle path
maskRect.path = maskCirclePath.CGPath
colorRed.setFill()
maskCirclePath.fill()
maskRect.fillRule = kCAFillRuleEvenOdd
self.layer.mask = maskRect
}
}
I'm not sure if my classes are being declared correctly. I made a group called "Vectors" where I planned to make a separate class for each drawing. I'm not sure if i'm supposed to select file -> new -> file and select a Cocoa Touch Class, or if i can just create a blank Swift file and write out my class code from scratch there. This is the option I was trying to figure out when my globial variables "went bad".
What's more strange is that the app compiles just fine in the simulator, my colors appear correctly for the classes applied to my icons that use the global color variables. But Xcode is throwing a fit so my #IBDesignables won't compile in storyboard and I have a bunch of red errors.
UPDATE
Somewhere along the way here, the Swift file that I posted in my question was removed from my projects "tests" target membership. The little checkbox was unchecked. I have no idea how I could have done this, but everything was back to normal until i got an xcode error whiting out all of my text and saying that editing is currently disabled. I ended up removing all of my swift files from "tests" (unchecking the "tests" target membership for all of the files"), then creating a new Objective C file which prompted Xcode to ask me to configure a new bridging header I transferred my old bridging header code to the new file. This seems to have fixed the problem. I'm not submitting this an an answer because I don't know what the actual problem was.

Resources