I have a button, how to take the state

i have a button, I have inheritance with the state of button. How to get it into an array, and after that - to take the state? Another meaning - how to make an array of not only buttons, but buttons with state, and after that - how to indicate the state after clicking certain CheckerTable.sharedInstance[i][j]. I could have two parallel arrays of buttons and states, but i'd like to haveonly one array.

1. I have an error "Cannot assign value of type '[[(UIButton, CheckEmpty.PlaceState)]]' to type '[[CheckEmpty]]'" and without ".0" in array.

2. How to het the state exactly from CheckerTable.sharedInstance[i][j]


class CheckEmpty: UIButton {

struct PlaceSet {

var background: UIColor?

var image: UIImage?

}


enum PlaceState {

case emp

case inn

case sel

case rea

}


let checkEmptyStyle = PlaceSet(background: UIColor(red: 0, green: 0, blue: 0, alpha: 0.18), image: nil)


var checkerPlace: UIButton!

var checkerState: PlaceState!


...

func place(checkerX: Int, checkerY: Int) -> (UIButton, PlaceState) {

let scale = screenSettings.minimalScaleFactor()

checkerPlace = UIButton(frame: CGRect(origin: CGPoint(x: checkerX*placeDistance*Int(100*scale)/100+Int(screenSettings.scWidth)/2-radius*Int(100*scale)/100, y: checkerY*placeDistance*Int(100*scale)/100+Int(screenSettings.scHeight)/2-radius*Int(100*scale)/100), size: CGSize(width: radius*2*Int(100*scale)/100, height: radius*2*Int(100*scale)/100)))

checkerPlace.backgroundColor = checkEmptyStyle.background

checkerPlace.layer.cornerRadius = CGFloat(radius*Int(100*scale)/100)

checkerPlace.layer.borderColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1).cgColor

checkerPlace.layer.borderWidth = 1

checkerPlace.showsTouchWhenHighlighted = false

checkerState = PlaceState.emp

return (checkerPlace, checkerState)

}

}


And the ViewController below...


struct CheckerTable {

static var sharedInstance = [[UIButton]](). //or should it be [[CheckEmpty]]?

}


class StartViewController: UIViewController {


let screenSettings = ScreenSettings()


let checkIn = CheckIn()

let checkEmpty = CheckEmpty()


var xX = 0

var yY = 0


override func viewDidLoad() {

super.viewDidLoad()


//utworzenie tablicy głównej - startowej - przyciski

CheckerTable.sharedInstance = [[

checkIn.place(checkerX: -1, checkerY: -1).0,

checkIn.place(checkerX: 0, checkerY: -1).0,

checkEmpty.place(checkerX: 1, checkerY: -1).0

],[

checkIn.place(checkerX: -1, checkerY: 0).0,

checkIn.place(checkerX: 0, checkerY: 0).0,

checkIn.place(checkerX: 1, checkerY: 0).0

],[

checkIn.place(checkerX: -1, checkerY: 1).0,

checkIn.place(checkerX: 0, checkerY: 1).0,

checkIn.place(checkerX: 1, checkerY: 1).0

]]


print(xX)

print(yY)


//wstawienie przycisków na ekran - wypełnienie planszy, oznaczenie każdego przycisku tagiem, definicja segue ad target

for j in 0...2 {

for i in 0...2 {

let loopTable = CheckerTable.sharedInstance[i][j]

view.addSubview(loopTable)

loopTable.tag = 10 * i + j

loopTable.translatesAutoresizingMaskIntoConstraints = true //make true otherwise does not display correct

loopTable.addTarget(self, action: #selector(gameUpdate), for: UIControl.Event.touchUpInside)

}

}


Thank You for help!

All this is not very clear.


To start with, some formatting would help


class CheckEmpty: UIButton {
    struct PlaceSet {
        var background: UIColor?
        var image: UIImage?
    }


    enum PlaceState {
        case emp
        case inn
        case sel
        case rea
    }


    let checkEmptyStyle = PlaceSet(background: UIColor(red: 0, green: 0, blue: 0, alpha: 0.18), image: nil)


    var checkerPlace: UIButton!
    var checkerState: PlaceState!


...
    func place(checkerX: Int, checkerY: Int) -> (UIButton, PlaceState) {
        let scale = screenSettings.minimalScaleFactor()
        checkerPlace = UIButton(frame: CGRect(origin: CGPoint(x: checkerX*placeDistance*Int(100*scale)/100+Int(screenSettings.scWidth)/2-radius*Int(100*scale)/100, y: checkerY*placeDistance*Int(100*scale)/100+Int(screenSettings.scHeight)/2-radius*Int(100*scale)/100), size: CGSize(width: radius*2*Int(100*scale)/100, height: radius*2*Int(100*scale)/100)))
        checkerPlace.backgroundColor = checkEmptyStyle.background
        checkerPlace.layer.cornerRadius = CGFloat(radius*Int(100*scale)/100)
        checkerPlace.layer.borderColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1).cgColor
        checkerPlace.layer.borderWidth = 1
        checkerPlace.showsTouchWhenHighlighted = false
        checkerState = PlaceState.emp
        return (checkerPlace, checkerState)
    }
}




struct CheckerTable {
    static var sharedInstance = [[UIButton]]().    //or should it be [[CheckEmpty]]?
}


class StartViewController: UIViewController {


    let screenSettings = ScreenSettings()


    let checkIn = CheckIn()
    let checkEmpty = CheckEmpty()


    var xX = 0
    var yY = 0


    override func viewDidLoad() {
        super.viewDidLoad()


        //utworzenie tablicy głównej - startowej - przyciski
        CheckerTable.sharedInstance = [[
                checkIn.place(checkerX: -1, checkerY: -1).0,
                checkIn.place(checkerX: 0, checkerY: -1).0,
                checkEmpty.place(checkerX: 1, checkerY: -1).0
            ],[
                checkIn.place(checkerX: -1, checkerY: 0).0,
                checkIn.place(checkerX: 0, checkerY: 0).0,
                checkIn.place(checkerX: 1, checkerY: 0).0
            ],[
                checkIn.place(checkerX: -1, checkerY: 1).0,
                checkIn.place(checkerX: 0, checkerY: 1).0,
                checkIn.place(checkerX: 1, checkerY: 1).0
            ]]


        print(xX)
        print(yY)


//wstawienie przycisków na ekran - wypełnienie planszy, oznaczenie każdego przycisku tagiem, definicja segue ad target
        for j in 0...2 {
            for i in 0...2 {
                let loopTable = CheckerTable.sharedInstance[i][j]
                view.addSubview(loopTable)
                loopTable.tag = 10 * i + j
                loopTable.translatesAutoresizingMaskIntoConstraints = true  //make true otherwise does not display correct
                loopTable.addTarget(self, action: #selector(gameUpdate), for: UIControl.Event.touchUpInside)
            }
        }


Let's now look at your question


i have a button,

Which object in code ?

Is it checkerPlace ?


I have inheritance with the state of button.

Is it CheckEmpty ?


How to get it into an array,

What do you want exactly to get in an array ?


and after that - to take the state?

????


Another meaning -

how to make an array of not only buttons,but buttons with state,


If you declare

struct ButtonWithState {
    var checkerPlace: UIButton
    var checkerState: PlaceState
}

then you create

var myArray : [ButtonWithState]


But you could probably simply use the tag of the button to hold the state, just changing the enum to make it Int


    enum PlaceState : Int {
        case emp = 1
        case inn
        case sel
        case rea
    }

var myArray : [UIButton]     // the tag will hold the state raw value


and after that - how to indicate the state after clicking certain CheckerTable.sharedInstance[i][j].

What is this array of array ?


I could have two parallel arrays of buttons and states, but i'd like to haveonly one array.

1. I have an error "Cannot assign value of type '[[(UIButton, CheckEmpty.PlaceState)]]' to type '[[CheckEmpty]]'" and without ".0" in array.

Which line do you get this ?

Is it line 2 of the second piece of code ?


2. How to het the state exactly from CheckerTable.sharedInstance[i][j]

With your declaration, CheckerTable.sharedInstance[i][j] is a UIButtonIf you have stored the state in the tag, then you get the state with

let state = PlaceState(rawValue: CheckerTable.sharedInstance[i][j].tag)



How is CheckIn defined ?

button - it is a CheckEmpty

..as an inheritance from UIButton (with implemented enum as a state (4 states)

I want to put CheckEmpty into the array

I want to take the state after clicking on the button from the sertain place of array


Thanks 🙂

class CheckIn: CheckEmpty {

let checkInStyle = PlaceSet.init(background: nil, image: UIImage(named: "checker_blue.png"))

override func place(checkerX: Int, checkerY: Int) -> (UIButton, CheckEmpty.PlaceState) {

var ball = super.place(checkerX: checkerX, checkerY: checkerY)

ball.0.setBackgroundImage(checkInStyle.image, for: UIControl.State.normal)

ball.1 = .inn

return ball

}

}

You are subclassing just to change the state of the instance ?


I fear the whole structure is to be rethought.


Anyway, you did not answer the questions I asked you (I wrote your questions in intalic) :


i have a button,

Which object in code ?

Is it checkerPlace ?


I have inheritance with the state of button.

Is it CheckEmpty ?


How to get it into an array,

What do you want exactly to get in an array ?


Another meaning -

how to make an array of not only buttons,but buttons with state,


If you declare

struct ButtonWithState { 
    var checkerPlace: UIButton 
    var checkerState: PlaceState 
} 

// then you create
var myArray : [ButtonWithState]


But you could probably simply use the tag of the button to hold the state, just changing the enum to make it Int


    enum PlaceState : Int { 
        case emp = 1 
        case inn 
        case sel 
        case rea 
    } 
 
var myArray : [UIButton]     // the tag will hold the state raw value


and after that - how to indicate the state after clicking certain CheckerTable.sharedInstance[i][j].

What is this array of array ?


I could have two parallel arrays of buttons and states, but i'd like to haveonly one array.

1. I have an error "Cannot assign value of type '[[(UIButton, CheckEmpty.PlaceState)]]' to type '[[CheckEmpty]]'" and without ".0" in array.

Which line do you get this error ?

Is it line 2 of the second piece of code ?


2. How to het the state exactly from CheckerTable.sharedInstance[i][j]

With your declaration, CheckerTable.sharedInstance[i][j] is a UIButtonIf you have stored the state in the tag, then you get the state with

let state = PlaceState(rawValue: CheckerTable.sharedInstance[i][j].tag)



Please answer if you want some help.

I have tested parts of your code, compiles without major issue.

So, where do you have error ?


And copy the exact code.

When you write

struct CheckerTable {
    static var sharedInstance = [[UIButton]]().    //or should it be [[CheckEmpty]]?
}

there is an extra comma at the end which is surely not in code

yes, subclassing to differ and after that indicate the state

I have answered, probably You missed it 🙂

button - it is a CheckEmpty

..as an inheritance from UIButton (with implemented enum as a state (4 states)

I want to put CheckEmpty into the array

I want to take the state after clicking on the button from the sertain place of array

the error appears on the beggining of filing array

CheckerTable.sharedInstance = [[checkIn.place(....

Shortly I would like to have an array of four different buttons, every kind of button has defined state. I have few methods in my game and it works fine. But I have there two parallel arrays - one of buttons, one of defined states. I want to have much simple code - one array of buttons with state. I try to make something quite obvious - but difficult for me: "if sharedInstance[...][...] has Placestate.empty, do ... or else... if sharedInstance[...][...] has Placestate.in, do ... etc." Sorry for that questions but I am learnig... I have written my simply game and all the learning is around that game. I have learned a lot, but sometimes things are not as easy as... they are easy after solving the problem. With or without help 😟 ... How to get the state from an array? After that, depending of the state, I do different methods to actualize an array. Some buttons become empty, some in.

And I do not why it is not possible to make an array of "myButton = (UIButton + myState)"

Thx for good energy 🙂

Claude did already suggest a good solution for that. He gave you sample code for a ButtonWithState struct that would keep the button and its state together.

Sorry, you don't answer the precise questions.


Notably, you say :


I have an error "Cannot assign value of type '[[(UIButton, CheckEmpty.PlaceState)]]' to type '[[CheckEmpty]]'" and without ".0" in array.


Which line do you get this error ?


For your last question: how to get the state:

- if you have stored it in tag, simply call

let state = PlaceState(rawValue: CheckerTable.sharedInstance[i][j].tag)

if you use the struct


struct ButtonWithState {
    var checkerPlace: UIButton
    var checkerState: PlaceState
}


// then you need to define shared instance as

static var sharedInstance = [[ButtonWithState]]()


you get the state with

let state =CheckerTable.sharedInstance[i][j].checkerState

Ok I will try it late afternoon 🙂

I would like to have an array of four different buttons, every kind of button has defined state.

ButtonWithState will allow to do this

struct ButtonWithState {
    var checkerPlace: UIButton
    var checkerState: PlaceState
}
var button = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 24))
var button1 = ButtonWithState(checkerPlace: button, checkerState: PlaceState.emp)
button = UIButton(frame: CGRect(x: 210, y: 10, width: 100, height: 24))     // change the button
var button2 = ButtonWithState(checkerPlace: button, checkerState: PlaceState.inn)
// etc


I have few methods in my game and it works fine. But I have there two parallel arrays - one of buttons, one of defined states. I want to have much simple code - one array of buttons with state.

So, if you use an Array of ButtonWithState, you will get this.


I try to make something quite obvious - but difficult for me: "if sharedInstance[...][...] has Placestate.empty, do ... or else... if sharedInstance[...][...] has Placestate.in, do ... etc."

So, if you want to test all the cases, do like this, instead of id { } else { }

To do this:

Make sure sharedInstance is using ButtonWithState

static var sharedInstance = [[ButtonWithState]]()


let state = CheckerTable.sharedInstance[i][j].checkerState
switch state {
     case  .emp :     // I understand emp means empty // do for empty
     case . inn :     // do for inn
     case .sel  :     // do for sel
     case .rea  :     // do for rea
}


And I do not why it is not possible to make an array of "myButton = (UIButton + myState)"

That's exactly what the ButtonWithState struct allows to do.

Well then, good morning. I have tried everything, the problem is probably straight and silmple for You, for me casting is difficult and I am not sure if it is possible. Thank You in advance. The example/training code below... and the error at the bottom.


------------------------------------------------------------------------------ Check.swift:


class Check: UIButton {

struct PlaceSet {

var background: UIColor?

var image: UIImage?

}


enum PlaceState {

case emp

case inn

}


let plState = PlaceState.emp


let screenSettings = ScreenSettings()


let checkEmptyStyle = PlaceSet(...) ...


let placeDistance = 44

let radius = 19


func place(checkerX: Int, checkerY: Int, state: PlaceState) -> UIButton {

let scale = screenSettings.minimalScaleFactor()

let checkerPlace = UIButton(...)

...

checkerPlace.showsTouchWhenHighlighted = false

switch state {

case .emp:

checkerPlace.backgroundColor = checkEmptyStyle.background

case .inn:

checkerPlace.setBackgroundImage(checkInStyle.image, for: UIControl.State.normal)

}

return checkerPlace

}

}


------------------------------------------------------------------------------ StartViewController.swift:


import UIKit

struct CheckerTable {

static var sharedInstance = [[Check]]()

}

class StartViewController: UIViewController {


let check = Check()


override func viewDidLoad() {

super.viewDidLoad()


CheckerTable.sharedInstance = [[

check.place(checkerX: 0, checkerY: 0, state: Check.PlaceState.inn),

check.place(checkerX: 1, checkerY: 0, state: Check.PlaceState.emp)

],[

check.place(checkerX: 0, checkerY: 1, state: Check.PlaceState.sel),

check.place(checkerX: 1, checkerY: 1, state: Check.PlaceState.emp)

]] as! [[Check]]


if CheckerTable.sharedInstance[0][0].plState == .emp {

print("empty")

} // ---> here is the problem - "Thread 1: Fatal error: Down-casted Array element failed to match the target type"

}

}

I have a button, how to take the state
 
 
Q