I have been building a drawing app programmatically in swift UIKit. I have been able to create UIButtons
for each case that I have defined inside a Pencil
enum. I can see each button appear for each Pencil.color
. My problem is that I have created a @obj
function called buttonClicked
that should assign the color that correspond to each button but when I click it, it does not work does not even print in the console that click event is detected.
Here is the variables that hold the properties of my pencil brush:
var lastPoint = CGPoint.zero
var color = UIColor.black
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false
this my buttonClicked
function that assigns each color:
@objc func buttonClicked(_ sender: UIButton){
guard let pencil = Pencil(tag: sender.tag) else {
return
}
color = pencil.color
if pencil == .eraser {
opacity = 1.0
}
print("button Clicked")
}
The function that creates the button for each Pencil.color
func createColorButton() -> [UIButton]{
var buttons: [UIButton] = []
for pencilCase in Pencil.allCases {
let button = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
button.backgroundColor = pencilCase.color
button.tag = pencilCase.hashValue
button.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)
buttons.append(button)
}
return buttons
}
and just to give context here is a reference of my Pencil
enum
enum Pencil: CaseIterable {
case black
case grey
case red
case darkblue
case lightBlue
case darkGreen
case lightGreen
case brown
case orange
case yellow
case eraser
init?(tag: Int) {
switch tag {
case 1:
self = .black
case 2:
self = .grey
case 3:
self = .red
case 4:
self = .darkblue
case 5:
self = .lightBlue
case 6:
self = .darkGreen
case 7:
self = .lightGreen
case 8:
self = .brown
case 9:
self = .orange
case 10:
self = .yellow
case 11:
self = .eraser
default:
return nil
}
}
// cases for penil.color
var color: UIColor {
switch self {
case .black:
return .black
case .grey:
return UIColor(white: 105/255.0, alpha: 1.0)
case .red:
return UIColor(red: 1, green: 0, blue: 0, alpha: 1.0)
case .darkblue:
return UIColor(red: 0, green: 0, blue: 1, alpha: 1.0)
case .lightBlue:
return UIColor(red: 51/255.0, green: 204/255.0, blue: 1, alpha: 1.0)
case .darkGreen:
return UIColor(red: 102/255.0, green: 204/255.0, blue: 0, alpha: 1.0)
case .lightGreen:
return UIColor(red: 102/255.0, green: 1, blue: 0, alpha: 1.0)
case .brown:
return UIColor(red: 160/255.0, green: 82/255.0, blue: 45/255.0, alpha: 1.0)
case .orange:
return UIColor(red: 1, green: 102/255.0, blue: 0, alpha: 1.0)
case .yellow:
return UIColor(red: 1, green: 1, blue: 0, alpha: 1.0)
case .eraser:
return .white
}
}
}
I tried to call the addTarget inside viewDidLoad
but that did not work either so here is the first version of my code
override func viewDidLoad() {
super.viewDidLoad()
let buttons = createColorButton()
stackView.spacing = 5
for button in buttons {
stackView.addArrangedSubview(button)
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.blue.cgColor
button.layer.cornerRadius = 10
}
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200)
])
setupImageViews()
}
What else could I try to do to make the createColorButton
work?
There are various ways to work with enums ... for your case, it's easy to use Pencil.allCases.enumerated()
and set the button tag to the index:
class ColorButtonsVC: UIViewController {
var color: UIColor = .white
var opacity: CGFloat = 1.0
let cLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
let buttons = createColorButton()
let stackView = UIStackView()
stackView.spacing = 5
for button in buttons {
stackView.addArrangedSubview(button)
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.blue.cgColor
button.layer.cornerRadius = 10
}
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
])
cLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cLabel)
NSLayoutConstraint.activate([
cLabel.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8.0),
cLabel.widthAnchor.constraint(equalToConstant: 200.0),
cLabel.heightAnchor.constraint(equalToConstant: 60.0),
cLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
])
cLabel.text = "Color"
cLabel.textAlignment = .center
//setupImageViews()
}
func createColorButton() -> [UIButton]{
var buttons: [UIButton] = []
for (idx, pencilCase) in Pencil.allCases.enumerated() {
let button = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
button.backgroundColor = pencilCase.color
// the Pencil enum starts at 1 instead of Zero
// so add 1 to the index
button.tag = idx + 1
button.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)
buttons.append(button)
}
return buttons
}
@objc func buttonClicked(_ sender: UIButton){
guard let pencil = Pencil(tag: sender.tag) else {
return
}
color = pencil.color
if pencil == .eraser {
opacity = 1.0
}
print("button Clicked:", sender.tag)
cLabel.backgroundColor = color
}
}