UIButton / UIView.animate заставляет кнопки мигать последовательно - PullRequest
1 голос
/ 30 октября 2019

Я делаю симонную игру в быстром темпе, где сигналы даны в enum [зеленый, желтый, красный, красный, синий] ... и я хочу, чтобы кнопки мигали при подаче сигналов. Код, который я использовал, чтобы кнопки мигал, был

extension UIButton {
    func blink() {
        self.alpha = 0.0;
        UIView.animate(withDuration: 0.6, //Time duration you want,
            delay: 0.0,
            options: [.curveEaseInOut, .autoreverse],
            animations: { [weak self] in self?.alpha = 1.0 },
            completion: { [weak self] _ in self?.alpha = 1.0 })
    }
}

, и в моей функции подачи сигнала я выполняю

    func giveSignal() {
        disableButton()
        signals = []
        for _ in 0...levelNum  {
//            stopBlinkAll()
            let randomSignal:Int = randomSource.nextInt(upperBound: 4)
            switch randomSignal {
                //Green
                case 0:
                    green.blink()
                    signals.append(Block.green)
//                    green.stopBlink()
                //Red
                case 1:
                    red.blink()
                    signals.append(Block.red)
//                    red.stopBlink()
                //Yellow
                case 2:
                    yellow.blink()
                    signals.append(Block.yellow)
//                    yellow.stopBlink()
                //Blue
                case 3:
                    blue.blink()
                    signals.append(Block.blue)
//                    blue.stopBlink()
            default:
                break
            }

        }
        let finalSeq:String = makeString()
        statusBar.text = finalSeq
    }

Но если сигналы даны как [Зеленый, Желтый,Красный], например, все зеленые, желтые и красные кнопки мигают одновременно. Как я могу это исправить, чтобы кнопки мигали одна за другой?

1 Ответ

0 голосов
/ 30 октября 2019

Сначала добавьте обработчик завершения к blink, потому что мы начнем следующий миг после того, как закончится предыдущий миг.

extension UIButton {
    func blink(completion: @escaping () -> Void) {
        self.alpha = 0.0;
        UIView.animate(withDuration: 0.6, //Time duration you want,
            delay: 0.0,
            options: [.curveEaseInOut],
            animations: { self.alpha = 1.0 },
            completion: { _ in
                UIView.animate(withDuration: 0.6,
                    delay: 0.0,
                    options: [.curveEaseInOut],
                    animations: { self.alpha = 0.0 },
                    completion: { _ in completion() })
             })
    }
}

Затем напишите функцию, которая принимает [Block] и индекс, который мигает кнопкой на этом индексе. Обратите внимание, как я передаю замыкание, которое вызывает blink(at:in:) снова, как завершение blink() вызовов:

func blink(at index: Int, in signals: [Block]) {
    guard index < signals.count else { return }
    let completion = { blink(at: index + 1, in: signals) }

    switch (signals[index]) {
        case .green: green.blink(completion: completion)
        case .red: red.blink(completion: completion)
        case .yellow: yellow.blink(completion: completion)
        case .blue: blue.blink(completion: completion)
    }
}

Теперь мы можем переписать giveSignal:

func giveSignal() {
    disableButton()
    signals = []
    for _ in 0...levelNum  {
        let randomSignal:Int = randomSource.nextInt(upperBound: 4)
        switch randomSignal {
        //Green
        case 0:
            signals.append(Block.green)
        //Red
        case 1:
            signals.append(Block.red)
        //Yellow
        case 2:
            signals.append(Block.yellow)
        //Blue
        case 3:
            signals.append(Block.blue)
        default:
            break
        }

    }
    blink(at: 0, in: signals) // This starts the sequence of blinks
    let finalSeq:String = makeString()
    statusBar.text = finalSeq
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...