I am developing an application using Swift 2 and Xcode 7 beta 6. I am trying to change the title of a button. My code:
print(randomNumber)
myButton.setTitle("\(randomNumber)", forState: UIControlState.Normal)
It gives me this:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
When I print randomNumber, however, I get the random integer that I wanted. What am I doing wrong in my code? Or is it just a problem with the beta version?
My full code:
//
// ViewController.swift
// Math Practice
//
// Created by Pranav Wadhwa on 9/6/15.
// Copyright © 2015 Pranav Wadhwa. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var firstNumber = Int()
var secondNumber = Int()
var sign = String()
let arrayOfSigns = ["add", "subtract", "divide", "mulitply"]
var correctAnswer = Int()
var percentage = Int()
var buttonWithCorrectAnswer = Int()
var correct = Int()
var total = Int()
var timer = NSTimer()
var seconds = 0
var minutes = 0
var inSession = false
var firstRandomAnswer = Int()
var secondRandomAnswer = Int()
var thirdRandomAnswer = Int()
var fourthRandomAnswer = Int()
#IBOutlet var timerLabel: UILabel!
#IBOutlet var questionLabel: UILabel!
#IBOutlet var correctLabel: UILabel!
#IBOutlet var percentageLabel: UILabel!
#IBOutlet var button1: UIButton!
#IBOutlet var button2: UIButton!
#IBOutlet var button3: UIButton!
#IBOutlet var button4: UIButton!
#IBOutlet var startPause: UIButton!
#IBAction func startPause(sender: AnyObject) {
if inSession == false {
createQuestion()
inSession = true
print(startPause)
startPause.setTitle("Pause", forState: UIControlState.Normal)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true)
} else if inSession == true {
inSession = false
startPause.setTitle("Start", forState: UIControlState.Normal)
questionLabel.text = ""
button1.setTitle("", forState: UIControlState.Normal)
button2.setTitle("", forState: UIControlState.Normal)
button3.setTitle("", forState: UIControlState.Normal)
button4.setTitle("", forState: UIControlState.Normal)
timer.invalidate()
}
}
#IBAction func reset(sender: AnyObject) {
seconds = 0
minutes = 0
correct = 0
percentage = 0
total = 0
correctLabel.text = "0/0"
timerLabel.text = "00:00"
percentageLabel.text = "0%"
questionLabel.text = ""
button1.setTitle("", forState: UIControlState.Normal)
button2.setTitle("", forState: UIControlState.Normal)
button3.setTitle("", forState: UIControlState.Normal)
button4.setTitle("", forState: UIControlState.Normal)
timer.invalidate()
inSession = false
}
#IBAction func button1(sender: AnyObject) {
if buttonWithCorrectAnswer == 1 {
correct += 1
}
total += 1
createQuestion()
}
#IBAction func button2(sender: AnyObject) {
if buttonWithCorrectAnswer == 2 {
correct += 1
}
total += 1
createQuestion()
}
#IBAction func button3(sender: AnyObject) {
if buttonWithCorrectAnswer == 3 {
correct += 1
}
total += 1
createQuestion()
}
#IBAction func button4(sender: AnyObject) {
if buttonWithCorrectAnswer == 4 {
correct += 1
}
total += 1
createQuestion()
}
func updateTime() {
seconds += 01
if seconds == 60 {
minutes++
seconds = 0
}
if seconds < 10 {
timerLabel.text = "\(minutes):0\(seconds)"
} else {
timerLabel.text = "\(minutes):\(seconds)"
}
}
func createQuestion() {
if correct != 0 && total != 0 {
percentage = correct / total
}
correctLabel.text = "\(correct)/\(total)"
percentageLabel.text = "\(percentage)%"
firstNumber = Int(arc4random_uniform(39))
secondNumber = Int(arc4random_uniform(39))
firstNumber -= 20
secondNumber -= 20
let i = Int(arc4random_uniform(4))
sign = arrayOfSigns[i]
if sign == "divide" {
firstNumber = Int(arc4random_uniform(39))
secondNumber = Int(arc4random_uniform(39))
firstNumber -= 20
secondNumber -= 20
}
if sign == "add" {
questionLabel.text = "\(firstNumber) + \(secondNumber)"
correctAnswer = firstNumber + secondNumber
}
if sign == "subtract" {
questionLabel.text = "\(firstNumber) - \(secondNumber)"
correctAnswer = firstNumber - secondNumber
}
if sign == "divide" {
firstNumber = firstNumber * secondNumber
questionLabel.text = "\(firstNumber) / \(secondNumber)"
correctAnswer = firstNumber / secondNumber
}
if sign == "multiply" {
questionLabel.text = "\(firstNumber) * \(secondNumber)"
correctAnswer = firstNumber * secondNumber
}
createAnswers()
}
func createAnswers() {
buttonWithCorrectAnswer = Int(arc4random_uniform(4) + 1)
//Insert Correct Answer
if buttonWithCorrectAnswer == 1 {
button1.setTitle("\(correctAnswer)", forState: UIControlState.Normal)
} else if buttonWithCorrectAnswer == 2 {
button2.setTitle("\(correctAnswer)", forState: UIControlState.Normal)
} else if buttonWithCorrectAnswer == 3 {
button3.setTitle("\(correctAnswer)", forState: UIControlState.Normal)
} else if buttonWithCorrectAnswer == 4 {
button4.setTitle("\(correctAnswer)", forState: UIControlState.Normal)
}
//Setup Fake Answer
if sign == "add" || sign == "subtract" || sign == "divide" {
firstRandomAnswer = Int(arc4random_uniform(79))
firstRandomAnswer -= 40
print("Hello wold")
print(firstRandomAnswer)
secondRandomAnswer = Int(arc4random_uniform(79))
secondRandomAnswer -= 40
while secondRandomAnswer == firstRandomAnswer {
secondRandomAnswer = Int(arc4random_uniform(79))
secondRandomAnswer -= 40
}
thirdRandomAnswer = Int(arc4random_uniform(79))
thirdRandomAnswer -= 40
while thirdRandomAnswer == secondRandomAnswer || thirdRandomAnswer == firstRandomAnswer {
thirdRandomAnswer = Int(arc4random_uniform(79))
thirdRandomAnswer -= 40
}
fourthRandomAnswer = Int(arc4random_uniform(79))
fourthRandomAnswer -= 40
while fourthRandomAnswer == thirdRandomAnswer || fourthRandomAnswer == secondRandomAnswer || fourthRandomAnswer == firstRandomAnswer {
fourthRandomAnswer = Int(arc4random_uniform(79))
fourthRandomAnswer -= 40
}
}
if sign == "multiply" {
firstRandomAnswer = Int(arc4random_uniform(799))
firstRandomAnswer -= 400
secondRandomAnswer = Int(arc4random_uniform(799))
secondRandomAnswer -= 400
while secondRandomAnswer == firstRandomAnswer {
secondRandomAnswer = Int(arc4random_uniform(799))
secondRandomAnswer -= 400
}
thirdRandomAnswer = Int(arc4random_uniform(799))
thirdRandomAnswer -= 400
while thirdRandomAnswer == secondRandomAnswer || thirdRandomAnswer == firstRandomAnswer {
thirdRandomAnswer = Int(arc4random_uniform(799))
thirdRandomAnswer -= 400
}
fourthRandomAnswer = Int(arc4random_uniform(799))
fourthRandomAnswer -= 400
while fourthRandomAnswer == thirdRandomAnswer || fourthRandomAnswer == secondRandomAnswer || fourthRandomAnswer == firstRandomAnswer {
fourthRandomAnswer = Int(arc4random_uniform(799))
fourthRandomAnswer -= 400
}
}
//Insert Fake Answers
if buttonWithCorrectAnswer != 1 {
button1.setTitle("\(firstRandomAnswer)", forState: UIControlState.Normal)
}
if buttonWithCorrectAnswer != 2 {
button2.setTitle("\(secondRandomAnswer)", forState: UIControlState.Normal)
}
if buttonWithCorrectAnswer != 3 {
button3.setTitle("\(thirdRandomAnswer)", forState: UIControlState.Normal)
}
if buttonWithCorrectAnswer != 4 {
button4.setTitle("\(fourthRandomAnswer)", forState: UIControlState.Normal)
}
}
#IBOutlet var backgroundImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
var image = arc4random_uniform(2)
image++
backgroundImage.image = UIImage(named: "background_" + String(image))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I think myButton is Optional and it's nil
My button was set to nil. I fixed this by reconnecting the outlet.
Related
I'm having an issue when my Spirit dies or is removed by removeFromParent()
command. The Spirit is removed successful but I can still shoot missiles even when the Spirit isn't there. My code for the GameScene.swft is as follows:
import SpriteKit
import GameplayKit
import CoreMotion
class GameScene: SKScene, SKPhysicsContactDelegate {
var starfield:SKEmitterNode!
var player = SKSpriteNode()
var scoreLabel:SKLabelNode!
var score:Int = 0 {
didSet {
scoreLabel.text = "Score: \(score)"
}
}
var gameTimer:Timer!
var possibleAliens = ["alien", "alien2", "alien3"]
let alienCategory:UInt32 = 0x1 << 1
let photonTorpedoCategory:UInt32 = 0x1 << 0
let photonshuttleCategory:UInt32 = 0x1 << 0
let photonalienCategory: UInt32 = 0x1 << 0
let shuttleCategory:UInt32 = 0x1 << 1
let motionManger = CMMotionManager()
var xAcceleration:CGFloat = 0
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
starfield = SKEmitterNode(fileNamed: "Starfield")
starfield.position = CGPoint(x: 0, y: 1472)
starfield.advanceSimulationTime(10)
self.addChild(starfield)
func restart(){
let mainStoryboard = UIStoryboard(name: "Start", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "Start")
self.view?.window?.rootViewController?.present(vc, animated: true, completion: nil)
}
starfield.zPosition = -1
player = SKSpriteNode(imageNamed: "shuttle")
player.position = CGPoint(x: self.frame.size.width / 2, y: player.size.height / 2 + 20)
var Ghost = player
Ghost.physicsBody = SKPhysicsBody(circleOfRadius: (Ghost.frame.height) / 2)
Ghost.physicsBody?.categoryBitMask = photonshuttleCategory
Ghost.physicsBody?.collisionBitMask = 0
Ghost.physicsBody?.contactTestBitMask = alienCategory
Ghost.physicsBody?.isDynamic = true
Ghost.physicsBody?.usesPreciseCollisionDetection = true
self.addChild(player)
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
self.physicsWorld.contactDelegate = self
scoreLabel = SKLabelNode(text: "Score: 0")
scoreLabel.position = CGPoint(x: 100, y: self.frame.size.height - 60)
scoreLabel.fontName = "AmericanTypewriter-Bold"
scoreLabel.fontSize = 36
scoreLabel.fontColor = UIColor.white
score = 0
if score >= 100{
player = SKSpriteNode(imageNamed: "Spaceship")
}
self.addChild(scoreLabel)
gameTimer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(addAlien), userInfo: nil, repeats: true)
if score >= 100{
gameTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(addAlien), userInfo: nil, repeats: true)
}
motionManger.accelerometerUpdateInterval = 0.1
motionManger.startAccelerometerUpdates(to: OperationQueue.current!) { (data:CMAccelerometerData?, error:Error?) in
if let accelerometerData = data {
let acceleration = accelerometerData.acceleration
self.xAcceleration = CGFloat(acceleration.x) * 0.75 + self.xAcceleration * 0.25
}
}
}
func addAlien () {
possibleAliens = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: possibleAliens) as! [String]
let alien = SKSpriteNode(imageNamed: possibleAliens[0])
let randomAlienPosition = GKRandomDistribution(lowestValue: 0, highestValue: 414)
let position = CGFloat(randomAlienPosition.nextInt())
alien.position = CGPoint(x: position, y: self.frame.size.height + alien.size.height)
alien.physicsBody = SKPhysicsBody(rectangleOf: alien.size)
alien.physicsBody?.isDynamic = true
alien.physicsBody?.categoryBitMask = alienCategory
alien.physicsBody?.contactTestBitMask = photonTorpedoCategory
alien.physicsBody?.collisionBitMask = 0
self.addChild(alien)
let animationDuration:TimeInterval = 6
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: position, y: -alien.size.height), duration: animationDuration))
actionArray.append(SKAction.removeFromParent())
alien.run(SKAction.sequence(actionArray))
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let delay = SKAction.wait(forDuration: 2.6)
self.run(delay)
fireTorpedo()
}
func fireTorpedo() {
self.run(SKAction.playSoundFileNamed("torpedo.mp3", waitForCompletion: false))
let torpedoNode = SKSpriteNode(imageNamed: "torpedo")
torpedoNode.position = player.position
torpedoNode.position.y += 60
torpedoNode.physicsBody = SKPhysicsBody(circleOfRadius: torpedoNode.size.width / 2)
torpedoNode.physicsBody?.isDynamic = true
torpedoNode.physicsBody?.categoryBitMask = photonTorpedoCategory
torpedoNode.physicsBody?.contactTestBitMask = alienCategory
torpedoNode.physicsBody?.collisionBitMask = 0
torpedoNode.physicsBody?.usesPreciseCollisionDetection = true
self.addChild(torpedoNode)
let animationDuration:TimeInterval = 0.3
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: player.position.x, y: self.frame.size.height + 10), duration: animationDuration))
actionArray.append(SKAction.removeFromParent())
torpedoNode.run(SKAction.sequence(actionArray))
}
func didBegin(_ contact: SKPhysicsContact) {
var firstBody:SKPhysicsBody
var secondBody:SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
}else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if (firstBody.categoryBitMask & photonTorpedoCategory) != 0 && (secondBody.categoryBitMask & alienCategory) != 0 {
torpedoDidCollideWithAlien(torpedoNode: firstBody.node as! SKSpriteNode, alienNode: secondBody.node as! SKSpriteNode)
}
}
func torpedoDidCollideWithAlien (torpedoNode:SKSpriteNode, alienNode:SKSpriteNode) {
let explosion = SKEmitterNode(fileNamed: "Explosion")!
explosion.position = alienNode.position
self.addChild(explosion)
self.run(SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: false))
torpedoNode.removeFromParent()
alienNode.removeFromParent()
self.run(SKAction.wait(forDuration: 2)) {
explosion.removeFromParent()
}
score += 5
}
func hitdidBegin(_ contact: SKPhysicsContact) {
var firstBody:SKPhysicsBody
var secondBody:SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
}else{
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if (firstBody.categoryBitMask & photonshuttleCategory) != 0 && (secondBody.categoryBitMask & alienCategory) != 0 {
spaceshipDidCollideWithNode(alienNode: secondBody.node as! SKSpriteNode, spaceShip: firstBody.node as! SKSpriteNode)
}
}
func spaceshipDidCollideWithNode (alienNode:SKSpriteNode, spaceShip:SKSpriteNode){
let explosion = SKEmitterNode(fileNamed: "Explosion")
explosion?.position = alienNode.position
self.addChild(explosion!)
self.run(SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: false))
alienNode.removeFromParent()
spaceShip.removeFromParent()
self.run(SKAction.wait(forDuration: 2)){
explosion?.removeFromParent()
}
score = 0
}
override func didSimulatePhysics() {
player.position.x += xAcceleration * 50
if player.position.x < -20 {
player.position = CGPoint(x: self.size.width + 20, y: player.position.y)
}else if player.position.x > self.size.width + 20 {
player.position = CGPoint(x: -20, y: player.position.y)
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
What I want to happen is that the fireTorpedo function will not be called when the Ghost/shuttle/player is removed.
Thank you.
There is a few ways to achieve what you want
1) You check if the players parent property is nil and not fire the torpedo if it is (I am not sure this is the best way)
func fireTorpedo() {
guard player.parent != nil else { return }
...
}
2) You could make your player an optional property
class GameScene: SKScene {
var player: SKSpriteNode?
override func didMove(to view: SKView) {
player = SKSpriteNode()
...
}
}
and when you remove it set it to nil
player = nil
and than not fire the torpedo if the player is nil
func fireTorpedo() {
guard player != nil else { return }
...
}
3) You can create another property in your GameScene class
var isPlayerRemoved = false
Than when you remove your player just set it to true
isPlayerRemoved = true
and than adjust your torpedo function to this
func fireTorpedo() {
guard !isPlayerRemoved else { return }
...
}
Hope this helps
Im having some trouble with method .disable in swift code. I have an array of Buttons and I want to disable the rest of Buttons when the correct Button (Target Button) is pressed. My array is call Buttons! Here are the action for the Buttons.
I have to have different names in the Buttons? or I can use .count method?
Thank you and appreciate everything.
#IBAction func btn1(sender: AnyObject) {
if answerNumber == 0 {
cwLabel.text = "You are Right!"
pickQuestion()
Buttons.count
} else {
cwLabel.text = "You are Wrong!"
pickQuestion()
}
}
#IBAction func btn2(sender: AnyObject) {
if answerNumber == 1 {
cwLabel.text = "You are Right!"
pickQuestion()
} else {
cwLabel.text = "You are Wrong!"
pickQuestion()
}
}
#IBAction func btn3(sender: AnyObject) {
if answerNumber == 2 {
cwLabel.text = "You are Right!"
pickQuestion()
} else {
cwLabel.text = "You are Wrong!"
pickQuestion()
}
}
#IBAction func btn4(sender: AnyObject) {
if answerNumber == 3 {
cwLabel.text = "You are Right!"
pickQuestion()
} else {
cwLabel.text = "You are Wrong!"
pickQuestion()
}
}
Use below line of code. It may help you...
for (var index = 0; index < arrayButton.count; index += 1) {
let btn : UIButton = arrayButton[index] as UIButton
btn.addTarget(self, action: #selector(self.toggleButtons toggleButtons(_:)), forControlEvents: .TouchUpInside)
}
func toggleButtons(button: UIButton) {
for (var index = 0; index < arrayButton.count; index += 1) {
if arrayButton[index] != button {
arrayButton[index].enabled = false
}
}
}
Do you mean to disable all of buttons or upressed ones? You can use toggle
func toggleButtons(button: UIButton) {
for (var index = 0; index < arrayButton.count; index += 1) {
if arrayButton[index] != button {
arrayButton[index].enabled = false
}
}
}
I'm trying to implement Pinch & Rotate gestures on a UIView who contains several subviews(UIButton,UITextView).
Code organized below to your convenience
I'm guessing i'm missing something. No idea what tho. Thank you!
Result :
Code
Scale :
var scaleAnchorPoint = CGPoint()
func handleSizeIncreasing(sender:UIPinchGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began
{
print("Began")
scaleAnchorPoint = self.center
}
else if sender.state == UIGestureRecognizerState.Changed
{
txtView.transform = CGAffineTransformScale(txtView.transform, sender.scale, sender.scale)
sender.scale = 1.0
self.frame.size = CGSizeMake(txtView.frame.width + buttonSize, txtView.frame.height + buttonSize)
self.center = scaleAnchorPoint
updateViews(scaleAnchorPoint)
print("Changed")
}
}
Rotate :
var rotateAnchorPoint = CGPoint()
func handleRotate(sender : UIRotationGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began
{
print("Began")
rotateAnchorPoint = self.center
}
else if sender.state == UIGestureRecognizerState.Changed
{
sender.view!.transform = CGAffineTransformRotate(sender.view!.transform, sender.rotation)
sender.rotation = 0
updateViews(rotateAnchorPoint)
print("Changed")
}
}
Side:
func updateViews(aroundPoint : CGPoint )
{
self.center = aroundPoint
txtView.frame.origin = CGPointMake(buttonSize / 2, buttonSize / 2)
txtView.contentSize = txtView.frame.size
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Figured it out. Simply, when the scale/frame changes, instead of accessing the Frame like i did here : self.frame.size = CGSizeMake(txtView.frame.width + buttonSize, txtView.frame.height + buttonSize)
Access self.bounds , like this -
self.bounds.size = CGSizeMake(txtView.frame.width + buttonSize, txtView.frame.height + buttonSize)
Enjoy!
I have the following Objective-C method:
- (void)addPolygonToMap {
NSInteger numberOfPoints = [self.coordinates count];
if (numberOfPoints > 4) {
CLLocationCoordinate2D points[numberOfPoints];
for (NSInteger i = 0; i < numberOfPoints; i++) {
points[i] = [self.coordinates[i] MKCoordinateValue];
}
self.polygon = [MKPolygon polygonWithCoordinates:points count:numberOfPoints];
[self.mapView addOverlay: self.polygon];
}
self.isDrawingPolygon = NO;
[self.drawPolygonButton setTitle:#"draw" forState:UIControlStateNormal];
self.canvasView.image = nil;
[self.canvasView removeFromSuperview];
}
My attempt at converting it to Swift:
func addPolygonToMap() {
var numberOfPoints: NSInteger = self.coordinates.count
if (numberOfPoints > 4) {
var points: [CLLocationCoordinate2D] = []
var coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(numberOfPoints)
for i in 0..<numberOfPoints {
points.append(coordsPointer[i])
}
self.polygon = MKPolygon(coordinates: &points, count: numberOfPoints)
self.mapView.addOverlay(self.polygon)
coordsPointer.dealloc(numberOfPoints)
}
self.isDrawingPolygon = false
self.drawPolygonButton.setTitle("Draw", forState: .Normal)
self.canvasView.image = nil
self.canvasView.removeFromSuperview()
}
Finally, when the delegate method is called it's not actually adding the overlay to the mapView. I can't see anything.
I'm assuming it's my self.addPolytonToMap() method, but I'm not 100% sure. The whole scenario works fine in my Objective-C project.
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if (overlay is MKPolygon) {
var overlayPathView = MKPolygonRenderer(overlay: overlay)
overlayPathView.fillColor = UIColor.cyanColor().colorWithAlphaComponent(0.2)
overlayPathView.strokeColor = UIColor.cyanColor().colorWithAlphaComponent(0.2)
overlayPathView.lineWidth = 5
return overlayPathView
} else if (overlay is MKPolyline) {
var overlayPathView = MKPolylineRenderer(overlay: overlay)
overlayPathView.strokeColor = UIColor.blueColor().colorWithAlphaComponent(0.7)
overlayPathView.lineWidth = 5
return overlayPathView
}
return nil
}
UPDATE:
I just noticed that in my Objective-C version, the points[i].latitude are coming through okay, however when I do the following I get a strange output:
println(coordsPointer[i].latitude)
Output:
1.63041663127611e-321
1.64523860065135e-321
1.65511991356818e-321
1.68970450877706e-321
1.7045264781523e-321
1.72922976044436e-321
This would explain why I don't see the overlay, however my experience with UnsafeMutablePointer<> is limited.
Fixed by modifying the addPolygonToMap() method:
func addPolygonToMap() {
var numberOfPoints: NSInteger = self.coordinates.count
if (numberOfPoints > 4) {
var points: [CLLocationCoordinate2D] = []
for i in 0..<numberOfPoints {
points.insert(self.coordinates[i].MKCoordinateValue, atIndex: i)
}
self.polygon = MKPolygon(coordinates: &points, count: numberOfPoints)
self.mapView.addOverlay(self.polygon)
}
self.isDrawingPolygon = false
self.drawPolygonButton.setTitle("Draw", forState: .Normal)
self.canvasView.image = nil
self.canvasView.removeFromSuperview()
}
Thanks to #Volker for the help.
Im trying to program a UIButton that performs that prints a message to the console. I can see the button and touch it but as soon as I touch it my app stops running and the console shows the following error:
Game[2743:63724] -[Game.GameScene buttonAction:]: unrecognized selector sent to instance 0x7a11ad00
2014-09-15 17:51:06.106 Game[2743:63724] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[GameGameScene buttonAction:]: unrecognized selector sent to instance 0x7a11ad00'
this is my code:
let imageButton = UIImage(named: "playbutton2") as UIImage
let buttonPlay = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
buttonPlay.frame = CGRectMake(screenSize.width / 2 , screenSize.height / 2, 100, 100)
buttonPlay.setImage(imageButton, forState: .Normal)
buttonPlay.addTarget(self, action: Selector("buttonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
buttonPlay.tag = 22
self.view.addSubview(buttonPlay)
and
func buttonAction(sender:UIButton!) {
println("Button tapped")
}
------- COMPLETE CODE ---------
import SpriteKit
class GameScene: SKScene {
var skyColor = SKColor()
var bird = SKSpriteNode()
var moving = SKNode()
var titleLabelNode = SKLabelNode()
var title = NSString()
let imageButton = UIImage(named: "playbutton2") as UIImage
let screenSize: CGRect = UIScreen.mainScreen().bounds
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.addChild(moving)
skyColor = SKColor(red: 113.0/255.0, green: 197.0/255.0, blue: 207.0/255.0, alpha: 1.0)
self.backgroundColor = skyColor
var birdTexture1 = SKTexture(imageNamed: "Bird1")
birdTexture1.filteringMode = SKTextureFilteringMode.Nearest
var birdTexture2 = SKTexture(imageNamed: "Bird2")
birdTexture2.filteringMode = SKTextureFilteringMode.Nearest
var animation = SKAction.animateWithTextures([birdTexture1, birdTexture2], timePerFrame: 0.2)
var flap = SKAction.repeatActionForever(animation)
bird = SKSpriteNode(texture: birdTexture1)
bird.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) + 150)
bird.runAction(flap)
bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height/2.0)
bird.physicsBody.dynamic = false
self.addChild(bird)
var groundTexture = SKTexture(imageNamed: "Ground")
groundTexture.filteringMode = SKTextureFilteringMode.Nearest
var moveGroundSprite = SKAction.moveByX(-groundTexture.size().width, y: 0, duration: NSTimeInterval(0.01 * groundTexture.size().width))
var resetGroundSprite = SKAction.moveByX(groundTexture.size().width, y: 0, duration: 0)
var moveGroundSpritesForever = SKAction.repeatActionForever(SKAction.sequence([moveGroundSprite, resetGroundSprite]))
for var i:CGFloat = 0; i<2 + self.frame.size.width / (groundTexture.size().width); ++i {
var sprite = SKSpriteNode(texture: groundTexture)
sprite.position = CGPointMake(i * sprite.size.width, sprite.size.height / 2)
sprite.runAction(moveGroundSpritesForever)
moving.addChild(sprite)
}
title = "Swing Bird"
titleLabelNode.fontName = "Helvetica-Bold"
titleLabelNode.fontSize = 80
//titleLabelNode.fontColor = SKColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.)
titleLabelNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) + 50)
titleLabelNode.text = "\(title)"
addChild(titleLabelNode)
let buttonPlay = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
buttonPlay.frame = CGRectMake(screenSize.width / 2 , screenSize.height / 2, 100, 100)
buttonPlay.setImage(imageButton, forState: .Normal)
buttonPlay.addTarget(self, action: Selector("buttonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
buttonPlay.tag = 22
self.view.addSubview(buttonPlay)
func buttonAction(sender:UIButton!) {
println("Button tapped")
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
Your function buttonAction is defined at the wrong level. It is currently a function inside didMoveToView instead of a function of the class GameScene.
You can fix it like this:
class GameScene: SKScene {
...
// Move the function here!
func buttonAction(sender:UIButton!) {
println("Button tapped")
}
override func didMoveToView(view: SKView) {
...