var ExitImg: UIImage!
var ExitButton: UIButton!
func missileHitAction(sender:UIButton!)
{
self.view.viewWithTag(12221)?.removeFromSuperview()
ExitImg = nil
ExitButton = nil
}
override func viewDidLoad() {
super.viewDidLoad()
ExitImg = UIImage(contentsOfFile: "/Users/Joca/Desktop/Game_dev/missile_gun1")
ExitButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
ExitButton.frame = CGRectMake(5, 285, 70, 30)
ExitButton.imageView?.tag = 12221
ExitButton.setBackgroundImage(ExitImg, forState: UIControlState.Normal)
ExitButton.addTarget(self, action: "missileHitAction:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(ExitButton)
}
This is a sample test project for deallocating buttons, on button press button should be deallocated, but its not :(
You are creating a button, but are not setting its tag. Instead, you are setting its image view's tag. Instead of:
ExitButton.imageView?.tag = 12221
I think you intended:
ExitButton.tag = 12221
Related
I am trying to create dynamic radio buttons based on Firebase data. I am hoping to arrange the buttons in a vertical stack, and essentially when they are clicked I would hope for them to disappear and display another view:
class PollController: UIViewController {
#IBOutlet weak var passLabel: UILabel!
#IBOutlet weak var pollImage: UIImageView!
var ref: FIRDatabaseReference!
var pollRef: FIRDatabaseReference!
var pass = ""
var passedImageURL = ""
var posX = 0;
var posY = 0;
var buttons = [UIButton]()
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
pollRef = ref.child("Polls").child(pass)
passLabel.text = pass
pollImage.sd_setImage(with: URL(string: passedImageURL), placeholderImage: UIImage(named: "test"))
pollRef.observe(FIRDataEventType.value, with: {(snapshot) in
let numberOfChildren = snapshot.childSnapshot(forPath: "answers").childrenCount
self.passLabel.text = String(numberOfChildren)
print(numberOfChildren)
var stackView = UIStackView(arrangedSubviews: self.buttons)
// create button1
for x in 0..<numberOfChildren {
let button = UIButton(frame: CGRect(x: self.posX, y: self.posY, width: 60, height: 20))
button.setTitleColor(UIColor.black, for: .normal)
button.setTitle("No", for: .normal)
button.setImage(UIImage(named: "checkbox untick.png")!, for: .normal)
// if the selected button cannot be reclick again, you can use .Disabled state
button.setImage(UIImage(named: "checkboxredtick.png")!, for: .selected)
button.tag = Int(x)
button.addTarget(self, action: #selector(self.buttonAction(sender:)), for: .touchUpInside)
stackView.addSubview(button)
self.buttons.append(button)
// create other buttons and add into buttons ...
}
})
// Do any additional setup after loading the view.
}
func buttonAction(sender: UIButton!){
for button in buttons {
button.isSelected = false
}
sender.isSelected = true
// you may need to know which button to trigger some action
// let buttonIndex = buttons.indexOf(sender)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
If you are using SWIFT 3.0 or later,
Then you must define add target method like below as _: is missing in the selector parameter.
button.addTarget(self, action: #selector(buttonAction(_:)), for: .TouchUpInside)
Also check id you have declares myStackview variable here. if you declared then try to add it as :
self.myStackview
Your button declaration is func buttonAction(sender: UIButton!). Note that there are no underscore before sender. This means that you need to specify the name of the argument when you call the function. Replace the underscore in the selector with the argument name sender
button.addTarget(self, action: #selector(buttonAction(sender:)), for: .touchUpInside)
You can also add an underscore in front of the argument name in the function.
func buttonAction(_ sender: UIButton!)
Also, I noticed that the code is in Swift 3 seeing most of the syntax. So, the control event for touch up inside in Swift 3 is touchUpInside and not TouchUpInside
UIbutton remove from MenuScene before I jump into GameScene, or when I don't remove, the button is visible in GameScene, but I draw in MenuScene, why is that? What is the best way to create buttons and change the images of button?
The code is:
var button: UIButton!
button = UIButton()
var buttonFrame = self.view!.frame
button?.frame = CGRectMake(0, 0, 200, 100)
let buttonImage = UIImage(named: "PlayButton")
let buttonClick = UIImage(named: "PlayButton-click")
button!.setImage(buttonImage, forState: UIControlState.Normal)
button!.setImage(buttonClick, forState: UIControlState.Highlighted)
button!.addTarget(self, action: "PlayButtonClick:", forControlEvents: UIControlEvents.TouchUpInside)
self.view?.addSubview(button)
func PlayButtonClick(sender: UIButton) {
self.view?.presentScene(GameScene(size:self.size),transition: .crossFadeWithDuration(1.2))
button.removeFromSuperview()
}
Try that in PlayButtonClick Method:
sender.hidden = true
This should probably do the trick.
button.hidden = true, or sender.hidden = true,
This hide the uibutton , but button is hide very early, before i enter the GameScene state, and i see that..
I have the following code.
import UIKit
class ViewController: UIViewController {
var button : UIButton?
override func viewDidLoad() {
super.viewDidLoad()
button = UIButton.buttonWithType(UIButtonType.System) as UIButton?
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I get the following error
ERROR:
'AnyObject' is not convertible to 'UIButton?'
I know I might be doing something fundamentally wrong. I would like to know what that is.
According to me:
I have declared button as an Optional UIButton
- Which I think means, that the value of button can be unset or nil
Therefore,
while initialising it the type is mentioned as UIButton?
Is this it right way ?
You can't cast to an optional UIButton in the way you're doing it. The correct way to cast to an optional UIButton is:
button = UIButton.buttonWithType(UIButtonType.System) as? UIButton
Interpret this as: This cast can either return nil or an UIButton object, resulting in an optional UIButton object.
Follow the below code
var myBtn = UIButton.buttonWithType(UIButtonType.System) as UIButton
//OR
var myBtn = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
//OR
var myBtn = UIButton()
myBtn.setTitle("Add Button To View Controller", forState: .Normal)
myBtn.setTitleColor(UIColor.greenColor(), forState: .Normal)
myBtn.frame = CGRectMake(30, 100, 200, 400)
myBtn.addTarget(self, action: "actionPress:", forControlEvents: .TouchUpInside)
self.view.addSubview(myBtn)
//Button Action
func actionPress(sender: UIButton!)
{
NSLog("When click the button, the button is %#", sender.tag)
}
Please try below code:
var button = UIButton(frame: CGRectMake(150, 240, 75, 30))
button.setTitle("Next", forState: UIControlState.Normal)
button.addTarget(self, action: "buttonTapAction:", forControlEvents: UIControlEvents.TouchUpInside)
button.backgroundColor = UIColor.greenColor()
self.view.addSubview(button)
This code should do the job.
button = UIButton.buttonWithType(UIButtonType.System) as! UIButton
In this case the force cast done with the ! is a safe option because the documentation does guarantee that the method returns a UIButton.
You can also create the button during the declaration of the property:
class ViewController: UIViewController {
var button = UIButton.buttonWithType(UIButtonType.System) as! UIButton
...
This way there is no need to declare the property as an optional type.
In my swift project I have a button and I want to print on a label how much time this button has been pressed.
How can I resolve this problem?
Adding to DHEERAJ's answer, you just need to add following code in func pressed(sender: UIButton!) to achieve what you need:
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
let dateString = dateFormatter.stringFromDate(date)
yourLabelName.text = dateString
Hope this might help.
To show how many times the button has been clicked you could class variable.
class SampleViewController: UIViewController {
var counter : Int!
#IBOutlet weak var yourLabelName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
counter = 1
let myFirstButton = UIButton(frame: CGRectMake(10, 50, 320, 40))
myFirstButton.setTitle("Tap Me", forState: .Normal)
myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myFirstButton.addTarget(self, action: "pressed:",forControlEvents: .TouchUpInside)
self.view.addSubview(myFirstButton)
}
func pressed(sender: UIButton!)
{
yourLabelName.text = "Pressed : \(counter)"
counter = counter + 1
}
}
Here is how button is created programmatically and prints a text in label when button is pressed.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myFirstButton = UIButton()
myFirstButton.setTitle("Tap Me", forState: .Normal)
myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myFirstButton.frame = CGRectMake(10, 50, 320, 40)
myFirstButton.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(myFirstButton)
}
func pressed(sender: UIButton!)
{
yourLabelName.text=#"Your Text is here"
}
The "go button" is not working as it should. When clicked it should hide the subviews. Here's the ViewController. I tried placing the final function in various places.
class timeViewController: UIViewController {
var score = 0
var buttonState: Int = 0;
var gameOver = UIView()
#IBAction func start(sender: AnyObject) {
if(displayTime.text != stoptimer.text){
var gameOver = UIView(frame: CGRectMake(0, 0, 0, 0))
gameOver.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.2)
//gameOver.opaque = false
self.view.addSubview(gameOver)
UIView.animateWithDuration(0, animations:{
gameOver.frame.size = CGSizeMake(667, 667)
})
let gobutton = UIButton()
let image = "button.png"
gobutton.setImage(UIImage(named: image), forState: .Normal)
gobutton.frame = CGRectMake(135, 300, 95, 95)
gobutton.addTarget(self, action: "pressed:" , forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(gobutton)
func pressed(sender: UIButton!){
gameOver.removeFromSuperview()
}
}
}
For removing your "GaneOver" view change to this code:
gameOver.removeFromSuperview()
And I hope you are writing "func pressed" outside of viewDidLoad or viewWillAppear
You will have to make gameOver a global variable by declaring it outside function and then do what you did like this:
class myClass {
var gameOver = UIView()
func myFunction() {/*edit everything including gameOverView's properties*/}
func pressed(sender: UIButton!) {
gameOver.removeFromSuperview()
}
}
Also make sure to write functions outside other functions like viewDidLoad but inside your class as it looks like you created that function inside another one. However you can call a function from within another one using something like myFunction() as separate line as is.
Hope that helps :)
You're re-declaring gameOver inside the if statement. Just remove var. Check this code out:
class ViewController: UIViewController {
var gameOver: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func start(sender: AnyObject) {
if(displayTime.text != stoptimer.text){
gameOver = UIView(frame: CGRectMake(0, 0, 0, 0))
gameOver.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.2)
//gameOver.opaque = false
self.view.addSubview(gameOver)
UIView.animateWithDuration(0, animations:{
self.gameOver.frame.size = CGSizeMake(667, 667)
})
let gobutton = UIButton()
let image = "button.png"
gobutton.setImage(UIImage(named: image), forState: .Normal)
gobutton.frame = CGRectMake(135, 300, 95, 95)
gobutton.addTarget(self, action: "pressed:" , forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(gobutton)
}
}
func pressed(sender: UIButton!){
self.gameOver.removeFromSuperview()
}
}