i have an array of buttons and I try to change the name of the buttons but I don't know how to access to all buttons when the array randomPokemons get new data in the function didSet.
I can change the title if I use a sender, but I want to find all buttons with tag 10 or the best way to find the buttons and iterate to change the name to new Pokemon name when the array randomPokemons get new data.
class MainViewController: UIViewController {
private var stackView: UIStackView!
private var pokemonImage: UIImageView!
private var titleLabel: UILabel!
private var scoreLabel: UILabel!
private var pokemonNameLabel: UILabel!
var randomPokemons: [PokemonModel] = []{
didSet {
setButtonTitles()
}
}
var correctAnswer: String = ""
var correctAnswerImage: String = ""
lazy var game = GameModel()
// MARK: - Properties
weak var coordinator: Coordinator?
weak var context: Context?
var viewModel: MainViewModel!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGray6
viewModel.apiCaller.delegate = self
setUpView()
setUpLayout()
viewModel.fetchPokemon()
}
private func setUpView() {
titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.text = "¿Who is that Pokemon?"
titleLabel.font = UIFont(name: "Arial Rounded MT Bold", size: 24)
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .center
scoreLabel = UILabel()
scoreLabel.translatesAutoresizingMaskIntoConstraints = false
scoreLabel.text = "Score: 0"
scoreLabel.numberOfLines = 0
scoreLabel.textAlignment = .center
pokemonImage = UIImageView(image: viewModel.getPokemonImage())
pokemonImage.translatesAutoresizingMaskIntoConstraints = false
pokemonImage.contentMode = .scaleAspectFit
pokemonNameLabel = UILabel()
pokemonNameLabel.translatesAutoresizingMaskIntoConstraints = false
pokemonNameLabel.text = "Yes, is a Pikachu"
pokemonNameLabel.numberOfLines = 0
pokemonNameLabel.textAlignment = .center
/*
nameOption2Button = UIButton(type: .system)
nameOption2Button.translatesAutoresizingMaskIntoConstraints = false
nameOption2Button.setTitle(viewModel.getTitleButton(), for: .normal)
nameOption2Button.setTitleColor(.black, for: .normal)
nameOption2Button.backgroundColor = .white
nameOption2Button.addTarget(self, action: #selector(option2Pressed), for: .touchUpInside)
*/
// stackView = UIStackView(arrangedSubviews: [nameOption1Button, nameOption2Button, nameOption3Button, nameOption4Button])
stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 24
// UIButtons
["Pokemon 1", "Pokemon 2", "Pokemon 3", "Pokemon 4"].forEach { pokemonName in
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(pokemonName, for: .normal)
button.setTitleColor(.black, for: .normal)
button.backgroundColor = .white
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
button.layer.shadowOpacity = 1.0
button.layer.shadowRadius = 0
button.layer.masksToBounds = false
button.layer.cornerRadius = 10.0
button.tag = 10
button.addTarget(self, action: #selector(optionPressed), for: .touchUpInside)
stackView.addArrangedSubview(button)
}
}
private func setUpLayout() {
view.addSubview(titleLabel)
view.addSubview(scoreLabel)
view.addSubview(pokemonImage)
view.addSubview(pokemonNameLabel)
view.addSubview(stackView)
/*
[nameOption1Button, nameOption2Button, nameOption3Button, nameOption4Button].forEach {
$0?.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
*/
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
scoreLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 2),
scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pokemonImage.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor, constant: 50),
pokemonImage.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pokemonNameLabel.topAnchor.constraint(equalTo: pokemonImage.bottomAnchor, constant: 2),
pokemonNameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stackView.topAnchor.constraint(equalTo: pokemonNameLabel.bottomAnchor, constant: 40),
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
// Width anchor 20 left x 20 right
stackView.widthAnchor.constraint(equalToConstant: view.bounds.width - 40),
])
}
@objc func optionPressed(sender: UIButton!) {
if let buttonTag = sender?.tag {
print(buttonTag)
}
}
func setButtonTitles(){
button.setTitle(randomPokemons[safe: index]?.name.capitalized, for: .normal)
}
}
// Array to store references to buttons
var buttons: [UIButton] = []
var randomPokemons: [PokemonModel] = [] {
didSet {
setButtonTitles()
}
}
// UIButtons
["Pokemon 1", "Pokemon 2", "Pokemon 3", "Pokemon 4"].enumerated().forEach { index, pokemonName in
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(pokemonName, for: .normal)
button.setTitleColor(.black, for: .normal)
button.backgroundColor = .white
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
button.layer.shadowOpacity = 1.0
button.layer.shadowRadius = 0
button.layer.masksToBounds = false
button.layer.cornerRadius = 10.0
button.tag = 10
button.addTarget(self, action: #selector(optionPressed), for: .touchUpInside)
stackView.addArrangedSubview(button)
// Add the button to the array
buttons.append(button)
}
Now, modify your setButtonTitles() function to update the titles of the buttons based on the randomPokemons array:
func setButtonTitles() {
// Iterate through the buttons and update their titles
for (index, button) in buttons.enumerated() {
if index < randomPokemons.count {
button.setTitle(randomPokemons[index].name.capitalized, for: .normal)
} else {
// Handle the case where there are fewer Pokemon names than buttons
button.setTitle("", for: .normal)
}
}
}