Spawning UIView every second at random CGPoint in Swift - ios

I am trying to "spawn" a UIView with a random UIColor as its background at a random CGPoint. I am using the code below which compiles fine with no bugs or anything but when it runs in the simulator I click start(the button on the first ViewController) but then go to ViewTwo but nothing happens(no "enemies" are spawned). Thank you for any help.
import UIKit
var randomPoint: CGPoint = CGPoint(x: Int(arc4random()%1000), y: Int(arc4random()%1000))
class ViewController: UIViewController {
#IBOutlet weak var startGameButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
class ViewTwo : UIViewController {
var timer = NSTimer()
func randomColor() -> UIColor {
let red = CGFloat(drand48())
let green = CGFloat(drand48())
let blue = CGFloat(drand48())
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
func spawnEnemy() {
let enemy: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
enemy.backgroundColor = randomColor()
enemy.center = randomPoint
self.view.addSubview(enemy)
}
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("spawnEnemy"), userInfo: nil, repeats: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

Your randomPoint needs to be recalculated in spawnEnemy, and is generating a random x y from 0 to 1000 (and should also be a float) It will likely be off the screen.

Related

What does margin is this? (PageMenu, swift, non-storyboard)

simulator ScreenShot
I have used PageMenu Library.
I have used swift and not story-board.
https://github.com/HighBay/PageMenu
How do I remove this margin ?
The following is source code.
ProjectDetailViewController.swift
class ProjectDetailViewController : UIViewController, CAPSPageMenuDelegate{
var projectId:NSInteger!
var firstView: FirstViewController!
var secondView: SecondViewController!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.whiteColor()
self.title = "PageMenu"
firstView = FirstViewController()
secondView = SecondViewController()
firstView.title = "test1"
secondView.title = "test2"
var controllerArray : [UIViewController] = []
controllerArray.append(firstView)
controllerArray.append(secondView)
let parameters: [CAPSPageMenuOption] = [
.MenuItemSeparatorWidth(0.0),
.UseMenuLikeSegmentedControl(true),
.MenuItemSeparatorPercentageHeight(0.0),
.SelectedMenuItemLabelColor(UIColor.hex("#ffee58", alpha: 1)),
.ScrollMenuBackgroundColor(UIColor.hex("#fffde7", alpha: 1)),
.SelectionIndicatorColor(UIColor.hex("#ffee58", alpha: 1)),
]
let topMargin:CGFloat = UIApplication.sharedApplication().statusBarFrame.size.height+self.navigationController!.navigationBar.frame.size.height;
let pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRectMake(0.0, topMargin, self.view.frame.width, self.view.frame.height-topMargin), pageMenuOptions: parameters)
pageMenu.delegate = self
self.addChildViewController(pageMenu)
self.view.addSubview(pageMenu.view)
pageMenu.didMoveToParentViewController(self)
}
func willMoveToPage(controller: UIViewController, index: Int){
NSLog("willMoveToPage");
}
func didMoveToPage(controller: UIViewController, index: Int){
NSLog("didMoveToPage");
}
}
FirstViewController.swift
class FirstViewController:UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSLog("x = %f y = %f width = %f height = %f", self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)
self.view.backgroundColor = UIColor.blueColor()
}
}
SecondViewController.swift
class SecondViewController:UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.greenColor()
}
}
thanks.

Swift Ints and some Doubles working but not all Doubles

What I am trying to do is increase the rate that the method spawnEnemy() is called on, and it works well using the starred numbers as Ints, but I felt like it goes by way too quickly so I thought of using Doubles and using the decimal point. However, if I go into the tenths spot of subtracting an amount from spawnRate in
self.spawnRate=spawnRate - 1.0 (I use anything but 0) spawnEnemy() will only be called on once in the simulator then nothing happens. Any advice or suggestions would be great. Thank you!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scoreLabel: UILabel!
var points: Int = 0
var tickCount=0.0 // **
var spawnRate=15.0 // Spawn every 15 seconds to start with..... **
var spawnTimer:NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
self.tickCount=self.spawnRate
self.spawnTimer=NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("tick"), userInfo: nil, repeats: true)
}
func tick() {
if (--tickCount == 0) { // **
self.spawnEnemy()
self.spawnRate=spawnRate - 0.5 // Change this to determine how quickly the spawn rate increases..... **
self.tickCount=self.spawnRate
}
}
func randomPoint() -> CGPoint {
let randomPoint: CGPoint = CGPoint(x:CGFloat(arc4random()%320),y:CGFloat(568-arc4random()%390))
return randomPoint
}
func randomColor() -> UIColor {
let red = CGFloat(drand48())
let green = CGFloat(drand48())
let blue = CGFloat(drand48())
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
func spawnEnemy() {
let enemy: UIButton = UIButton(frame: CGRect(x: 160, y: 160, width: 100, height: 100))
enemy.backgroundColor = randomColor()
enemy.center = randomPoint()
enemy.addTarget(self, action: Selector("buttonPushed:"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(enemy)
}
func buttonPushed(sender : UIButton) {
if sender.frame.height < 50 || sender.frame.width < 50 {
sender.frame = CGRectMake(sender.frame.origin.x, sender.frame.origin.y, 50, 50)
sender.backgroundColor = randomColor()
sender.center = randomPoint()
return
}
while sender.backgroundColor != UIColor.blackColor() {
points = points + 1
scoreLabel.textAlignment = .Center
scoreLabel.text = "\(points)"
scoreLabel.backgroundColor = UIColor.blackColor()
sender.backgroundColor = UIColor.blackColor()
}
}
}
I think what's happening is you're trying to test a double with the equality operator. The problem is that there's always a bit of complexity in how doubles are stored that makes it very difficult to compare them with equality. Instead you need to do something like this:
if (--tickCount <= 0) {
That way you catch it going negative for sure, otherwise it can go right past 0 and continue to count down.

Using Decreasing Variable as NSTimeInterval in swift

I am trying to decrease a Double variable by 0.05 every second to speed up the function spawnEnemy() but I cannot find a way that works well. So, I am trying to pretty much "spawn" more enemies(UIButtons) in a shorter amount of time. Any help would be great and very appreciated. Thank you! My code below compiles fine but does not speed up the NSTimer controlling the function spawnEnemy()
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scoreLabel: UILabel!
var points: Int = 0
func randomPoint() -> CGPoint {
let randomPoint: CGPoint = CGPoint(x:CGFloat(arc4random()%320),y:CGFloat(568-arc4random()%390))
return randomPoint
}
func randomColor() -> UIColor {
let red = CGFloat(drand48())
let green = CGFloat(drand48())
let blue = CGFloat(drand48())
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
func spawnEnemy() {
let enemy: UIButton = UIButton(frame: CGRect(x: 160, y: 160, width: 100, height: 100))
enemy.backgroundColor = randomColor()
enemy.center = randomPoint()
enemy.addTarget(self, action: Selector("buttonPushed:"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(enemy)
}
func buttonPushed(sender : UIButton) {
if sender.frame.height < 50 || sender.frame.width < 50 {
sender.frame = CGRectMake(sender.frame.origin.x, sender.frame.origin.y, 50, 50)
sender.backgroundColor = randomColor()
sender.center = randomPoint()
return
}
sender.backgroundColor = UIColor.blackColor()
points = points + 1
scoreLabel.textAlignment = .Center
scoreLabel.text = "\(points)"
scoreLabel.backgroundColor = UIColor.blackColor()
}
func decreaseDouble() -> Double {
var num: Double = 2.0
num = num - 0.05
return num
}
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(decreaseDouble(), target: self, selector: Selector("spawnEnemy"), userInfo: nil, repeats: true)
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("decreaseDouble"), userInfo: nil, repeats: false)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Below is my new code. Any finals things or should this work? I also added a while statement so you can only receive points while the enemy is not black,otherwise you could just keep clicking on wherever enemies have been spawned(but were clicked) and keep getting points. However, now when i run the application two enemies are already spawned but i can still click on them(only being allowed to get two points)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scoreLabel: UILabel!
var points: Int = 0
func randomPoint() -> CGPoint {
let randomPoint: CGPoint = CGPoint(x:CGFloat(arc4random()%320),y:CGFloat(568-arc4random()%390))
return randomPoint
}
func randomColor() -> UIColor {
let red = CGFloat(drand48())
let green = CGFloat(drand48())
let blue = CGFloat(drand48())
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
func spawnEnemy() {
let enemy: UIButton = UIButton(frame: CGRect(x: 160, y: 160, width: 100, height: 100))
enemy.backgroundColor = randomColor()
enemy.center = randomPoint()
enemy.addTarget(self, action: Selector("buttonPushed:"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(enemy)
}
func buttonPushed(sender : UIButton) {
if sender.frame.height < 50 || sender.frame.width < 50 {
sender.frame = CGRectMake(sender.frame.origin.x, sender.frame.origin.y, 50, 50)
sender.backgroundColor = randomColor()
sender.center = randomPoint()
return
}
while sender.backgroundColor != UIColor.blackColor() {
points = points + 1
scoreLabel.textAlignment = .Center
scoreLabel.text = "\(points)"
scoreLabel.backgroundColor = UIColor.blackColor()
sender.backgroundColor = UIColor.blackColor()
}
delayTime -= 0.05
}
var delayTime: Double = 2.0
override func viewDidLoad() {
super.viewDidLoad()
delayTime = 2.0
NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("spawnEnemy"), userInfo: nil, repeats: false)
NSTimer.scheduledTimerWithTimeInterval(delayTime, target: self, selector: Selector("spawnEnemy"), userInfo: nil, repeats: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
Repeating NSTimers always fire on the same interval once you start them.
If you want to use a decreasing interval then instead of a repeating timer I suggest use use a single "one-shot" timer (not 2 timers). Create the timer with repeats:false. Then in your timer method (spawnEnemy, in your case) decrement your time interval and use it to create a new timer (also with repeats:false) using the new, shorter interval and calling the same method.
Your decreaseDouble function isn't going to work as written. It will always return the same value of 2.0 - 0.05, since you set num to 2.0 each time the function called. Instead get rid of the decreaseDouble function. Create an instance variable delayValue and assign it a value (2.0, for example) in your viewDidLoad. Then just subtract 0.05 from it each time spawnEnemy is called, spawn a new enemy, and create a new timer if delayValue hasn't gotten too small. (When delayValue gets really small you're going to be spawning 10 enemies a second. Eventually delayValue will go to zero, and a timer interval should not be <= 0.0.
You have the right idea. I would use the repeating timer as a 'tick' and then keep two properties - One is the tick count and the other is the tick count before a new enemy is spawned. By decreasing the latter you can speed up the rate of spawning.
Something like this
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scoreLabel: UILabel!
var points: Int = 0
var tickCount=0
var spawnRate=100 // Spawn every 10 seconds to start with
var spawnTimer:NSTimer!
override func viewDidLoad() {
super.viewDidLoad()
self.tickCount=self.spawnRate
self.spawnTimer=NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("tick"), userInfo: nil, repeats: true)
}
func tick() {
if (--tickCount == 0) {
self.spawnEnemy()
self.spawnRate=spawnRate - 2 // Change this to determine how quickly the spawn rate increases
self.tickCount=self.spawnRate
}
}
You can modify the tick rate and tick decrement amounts as required to give you the range you are after

Add Target for UIButton Not Called

I have two view controllers that I am currently working with. In my CathyTaskLogMessageViewController, I have this code:
func defaultPictureButtonTapped(sender: UIButton) {
let imageViewerViewController = ImageViewerViewController()
imageViewerViewController.image = self.defaultPictureButton.imageView!.image
imageViewerViewController.cancelButtonImage = UIImage(named: "cancelButtonImage")
imageViewerViewController.centerPictureFromPoint(self.defaultPictureButton.frame.origin, ofSize: self.defaultPictureButton.frame.size, withCornerRadius: self.defaultPictureButton.layer.cornerRadius)
self.view.addSubview(imageViewerViewController.view)
}
And in my ImageViewerViewController, I have this code:
var image: UIImage!
var imageView: UIImageView!
var scrollView: UIScrollView!
var disableSavingImage: Bool!
var pan: UIPanGestureRecognizer!
var cancelButton: UIButton!
var cancelButtonImage: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0)
setCancelButton()
}
func setCancelButton() {
self.cancelButton = UIButton(type: UIButtonType.RoundedRect)
self.cancelButton.addTarget(self, action: "cancelButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
self.cancelButton.setImage(cancelButtonImage, forState: UIControlState.Normal)
self.cancelButton.tintColor = UIColor.whiteColor()
self.cancelButton.frame = CGRectMake(self.view.frame.size.width - (self.cancelButtonImage.size.width * 2) - 18, 18, self.cancelButtonImage.size.width * 2, self.cancelButtonImage.size.height * 2)
self.view.addSubview(self.cancelButton)
}
func cancelButtonTapped(sender: UIButton) {
print("cancelButtonTapped")
}
func centerPictureFromPoint(point: CGPoint, ofSize size: CGSize, withCornerRadius radius: CGFloat) {
UIView.animateWithDuration(0.3, animations: { () -> Void in
self.view.backgroundColor = UIColor(colorLiteralRed: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
}) { (finished: Bool) -> Void in
}
}
Now, when I tap the cancel button, it should print "cancelButtonTapped" in the console. However, there is not output from the console.
I think the problem has to do with the button being in a different subview perhaps? I'm not exactly sure. Anybody have a solution to this problem?
Also, when the cancel button loads, it loads from the left and moves to the right. Is there a way that the button just appears on the top right hand corner?
Thank you in advance for your help.
change background color, so you can identify the problem.
put this line in viewDidLayoutSubviews() this method so it loads from the left and moves to the right can solve
code:
override func viewDidLayoutSubviews() {
self.cancelButton.frame = CGRectMake(self.view.frame.size.width - (self.cancelButtonImage.size.width * 2) - 18, 18, self.cancelButtonImage.size.width * 2, self.cancelButtonImage.size.height * 2)
}

How do I switch between two colors on a UIView with UITapGestureRecognizer

I am trying to set up a gesture recognizer (UITapGestureRecognizer) that works by clicking once and changing the view color to blue and in the second click to change it to yellow and then back to the default color red.
class ViewController: UIViewController {
var squarView:UIView!;
var squarIsBlue:Bool = true;
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
squarView = UIView(frame: CGRect(x: 130, y: 130, width: 150, height: 150));
squarView.backgroundColor = UIColor.redColor();
var squarTap = UITapGestureRecognizer(target: self, action: "tapMe:");
squarView.addGestureRecognizer(squarTap);
squarView.userInteractionEnabled = true;
view.addSubview(squarView);
}
func tapMe(sender:UIGestureRecognizer){
squarView.backgroundColor = UIColor.blueColor();
if (squarIsBlue == false){
squarView.backgroundColor = UIColor.yellowColor();
if(squarIsBlue == true){
squarView.backgroundColor = UIColor.redColor();
}
squarIsBlue = true
}
squarIsBlue = false;
println("Squar Tapped!!!");
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
What am I doing wrong?
You have mistake in tapMe logic. In this particular case it's better to use Integer variable instead of Boolean, since you have 3 states (Red,Blue,Yellow)...
Try this :
import UIKit
class ViewController: UIViewController {
private var tapGesture : UITapGestureRecognizer!
private var childView : UIView!
private let colorPalette = [UIColor.redColor(),UIColor.blueColor(),UIColor.yellowColor()]
private var currentColorIdx = 0 {
didSet{
childView.backgroundColor = colorPalette[currentColorIdx]
}
}
override func viewDidLoad() {
super.viewDidLoad()
tapGesture = UITapGestureRecognizer(target: self, action: "didTap:")
childView = UIView(frame: CGRect(x: 130, y: 130, width: 150, height: 150))
childView.backgroundColor = colorPalette.first
self.view.addSubview(childView)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
childView.addGestureRecognizer(self.tapGesture)
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(true)
childView.removeGestureRecognizer(self.tapGesture)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func didTap(gesture: UIGestureRecognizer){
currentColorIdx = (currentColorIdx + 1 ) % colorPalette.count
}
}
You can set your squarIsBlue variable as int instead of Bool, to set color like, 0 = Red (Default), 1 = Blue, 2= Yellow,
So now, In viewdidLoad, set something like
squarIsBlue=0
squarView.backgroundColor = UIColor.redColor();
Change your Tap Method like
func tapMe(sender:UIGestureRecognizer){
squarView.backgroundColor = UIColor.blueColor();
if (squarIsBlue == 0){
squarView.backgroundColor = UIColor.blueColor();
squarIsBlue=1;
else if (squarIsBlue == 1) {
squarView.backgroundColor = UIColor.yellowColor();
squarIsBlue =2
}
else if (squarIsBlue==2) {
squarView.backgroundColor = UIColor.redColor();
squarIsBlue=0;
}
println("Squar Tapped!!!");
}
Hope, this help you,
HTH, Enjoy coding !!

Resources