Как сократить этот код, чтобы предотвратить дублирование кода?
У меня был этот вопрос довольно долго. Я пытаюсь визуализировать проблему с 3 дверями, просто для удовольствия и практики с Swift. Так что я:
3 двери, и, следовательно, 3 различных IBActions и 3 функции для всех дверей. Все эти функции абсолютно одинаковы, однако в каждом коде различается только количество дверей. Мне было интересно, могу ли я сократить этот код?:
func openSecondChoice(whatDoorIsClickedOn: Int)
{
if whatDoorIsClickedOn == 1
{
if whatDoorIsClickedOn == doorWithNumber
{
UIButtonDoor1.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
}
else
{
UIButtonDoor1.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
}
}
if whatDoorIsClickedOn == 2
{
if whatDoorIsClickedOn == doorWithNumber
{
UIButtonDoor2.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
}
else
{
UIButtonDoor2.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
}
}
if whatDoorIsClickedOn == 3
{
if whatDoorIsClickedOn == doorWithNumber
{
UIButtonDoor3.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
}
else
{
UIButtonDoor3.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
}
}
}
Юк! Этот код такой уродливый! Если пользователь нажимает на door1, например, я вызываю функцию "openSecondChoise(whatDoorIsClickedOn: 1)". Есть ли способ сократить это? Спасибо! Я не использую классы здесь, я должен использовать их?
3 ответа
Обычно, когда вы начинаете суффиксировать имена переменных с 1
, 2
, 3
и т.д., пришло время использовать массив. Для этого и нужны массивы.
С массивом uiButtonDoors
который содержит ваш UIButtonDoor1
...UIButtonDoor3
Ваша функция может выглядеть так:
func openSecondChoice(whatDoorIsClickedOn: Int) {
let imageName = whatDoorIsClickedOn == doorWithNumber ? "doorWithMoney" : "doorWithGoat"
uiButtonDoors[whatDoorIsClickedOn - 1].setBackgroundImage(UIImage(named: imageName), for: UIControlState.normal)
}
func openSecondChoice(whatDoorIsClickedOn: Int) {
let imageName = whatDoorIsClickedOn == doorWithNumber ? "doorWithMoney" : "doorWithGoat"
let image = UIImage(named: imageName)
let button: UIButton
switch whatDoorIsClickedOn {
case 1:
button = UIButtonDoor1
case 2:
button = UIButtonDoor2
case 3:
button = UIButtonDoor3
default:
fatalError("Cannot be. Switch must be exhaustive, that's why we need to use 'default' for a switch on Int.")
}
button.setBackgroundImage(image, for: .normal)
}
Для более короткой версии проверьте ответ @tuple_cat.
Другой подход, для развлечения.
import UIKit
class DoorGame {
func setupButtons() {
let buttons = [UIButton(), UIButton(), UIButton()]
for (index, button) in buttons.enumerated() {
button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
button.setTitle("\(index)", for: .normal)
}
let winningIndex = Int(arc4random_uniform(UInt32(buttons.count)))
buttons[winningIndex].tag = 1
}
@objc func buttonTapped(_ sender: UIButton) {
let imageName = sender.tag == 1 ? "doorWithMoney" : "doorWithGoat"
let image = UIImage(named: imageName)
sender.setBackgroundImage(image, for: .normal)
}
}