7

In my program 2 functions (IBAction player.Move(UIButton) and autoMove()) are supposed to be called by turns till all of the fields (UIButtons) has been clicked. For this I've created a function play(). However, I don't know how can I put the IBAction playerMove inside of play() function, because I need no parameter here.
I've found some answers and tried self.playerMove(nil) and self.playerMove(self) but it doesn't work.

import UIKit

class ViewController: UIViewController {

@IBOutlet var cardsArray: Array<UIButton> = [] 

var randomCard = 0


override func viewDidLoad() {
    super.viewDidLoad()
    self.play()
    // Do any additional setup after loading the view, typically from a nib.
}


func play () {
    self.autoMove()
    self.playerMove(self) // <----- here is my problem

}



@IBAction func playerMove(sender: UIButton) {

    switch (sender) {

    case self.cardsArray[0]:
        self.cardPressedAll(0)

    case self.cardsArray[1]:
        self.cardPressedAll(1)

    case self.cardsArray[2]:
        self.cardPressedAll(2)

    case self.cardsArray[3]:
        self.cardPressedAll(3)

    default: break
    }

}


func cardPressedAll (cardNumber: Int) {

    self.cardsArray[cardNumber].enabled = false

    self.cardsArray[cardNumber].setBackgroundImage(UIImage(named: "cross"), forState: UIControlState.Normal)

    self.cardsArray.removeAtIndex(cardNumber)

}


  func autoMove (){

    self.randomCard  = Int(arc4random_uniform(UInt32(self.cardsArray.count)))

    self.cardsArray[self.randomCard].enabled = false

    self.cardsArray[self.randomCard].setBackgroundImage(UIImage(named: "nought"), forState: UIControlState.Normal)

    self.cardsArray.removeAtIndex(self.randomCard)
}

}
Dandy
  • 929
  • 2
  • 14
  • 23

3 Answers3

8

Either you have to call playerMove: without a button, in which case you have to declare the sender parameter as an optional. Like:

@IBAction func playerMove(sender: UIButton?) {

UIButton means that you have to pass in a button. nil is not a button, but with UIButton?, that is to say Optional<UIButton>, nil is a valid value meaning the absence of a button.

Or you have to work out which button you want to pass to playerMove: to make it do what you want. Sit down and work out what you want to have happen, and what the code needs to do in order to make that happen.

Jesper
  • 7,477
  • 4
  • 40
  • 57
  • Unfortunately `@IBAction func playerMove(sender: UIButton?)` gives me errors in every `case`: `Value of optional type 'UIButton?' not upwrapped; did you mean to use '!' or '?'`. Both ? and ! give more errors ;) When it comes to **or**: I don't know which button I want to pass to `playerMove` because in this function a player chooses a button. In `autoMove()` a button is randomly chosen by the computer. – Dandy Dec 09 '14 at 13:23
  • So it sounds like you don't need to make it optional, the code will always deal with a button, but you do need to make the code in `play` figure out which button to pass. I have no idea what you want to happen, so I can't help you with that. You'll have to work out what you want to happen. – Jesper Dec 09 '14 at 13:55
  • thank you for your patience, however, I don't understand. By calling `playerMove` action I want a player to choose a field (which is a button), then, according to my code this field will be disabled, its background will change and then a computer chooses randomly a field (`autoMove`)and it also becomes disabled and the background will change, then again - player's move, then computer's move till all the fields are disabled. How can I show the function `play()` which button to pass? – Dandy Dec 09 '14 at 15:51
  • You would have to store away which button you use somewhere, so that you can know which button the next time. Generally, using the exact UI control creates a bunch of problems. I'd think about having a class describing your game's state and handle the information there instead. – Jesper Dec 09 '14 at 16:09
5

Try

self.playerMove(UIButton())

Your func playerMove has parameters expecting sender to be of type UIButton, self or nil would be an unexpected object.

Edit: You could us optional parameters by placing ?. This would allow you to call self.playerMove(nil) if needed.

@IBAction func playerMove(sender: UIButton?) {
    if sender != nil {
        //handle when button is passed
    } else {
        //handle when nil is passed
    }
}
Chameleon
  • 1,608
  • 3
  • 21
  • 39
1

doSomeTask(UIButton()) in swift 5.0 and onward worked for me

Hassan Kalhoro
  • 182
  • 2
  • 8