Swift:多个功能同时工作

时间:2017-08-15 23:32:08

标签: swift uibutton avaudioplayer viewcontroller

在我的应用程序中,我有2个UIButtons,每个按钮播放2个声音(播放一个声音,暂停,播放另一个声音),每次按下UIButtons图像时,我的应用程序也有一些标签。问题就是当我按下一个UIButton(需要大约4秒才能播放和完成声音)时我无法按下另一个按钮,甚至在标签之间切换,应用程序冻结,直到UI按钮的动作完成,然后我可以按其他按钮或切换标签。 这是我的代码:

import UIKit
import AVFoundation
import CoreData


class FirstViewController: UIViewController {

var player:AVAudioPlayer = AVAudioPlayer()

var player2:AVAudioPlayer = AVAudioPlayer()


@IBAction func play(_ sender: Any) {

    player.play()
    sleep(1)
    player2.play()
}

@IBAction func play2(_ sender: Any) {
    player.play()
    sleep(1)
    player2.play()  
}


@IBOutlet weak var play: UIButton!
@IBOutlet weak var play2: UIButton!

var buttonActive = false

@IBAction func pPressed(_ sender: Any) {
    if buttonActive {
        play.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
    } else {
        play.setBackgroundImage(UIImage(named: "Switch-Icon-40"), for: .normal)
    }
    buttonActive = !buttonActive
}

@IBAction func p2Pressed(_ sender: Any) {
    if buttonActive {
        play2.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
    } else {
        play2.setBackgroundImage(UIImage(named: "Switch-Icon-40"), for: .normal)
    }
    buttonActive = !buttonActive
}

override func viewDidLoad() {
    super.viewDidLoad()
    play.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
    play2.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)

do

    {

        let audioPath = Bundle.main.path(forResource: "DTMF-1", ofType: "mp3")
        try player = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)

        let audioPath2 = Bundle.main.path(forResource: "DTMF-2", ofType: "mp3")
        try player2 = AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath2!) as URL)

 }

有没有办法让我的应用更快?

1 个答案:

答案 0 :(得分:0)

实施做某事,暂停并做其他事情的一种着名方法是使用Timer

以下代码还包括:

  • 如何正确实例化AVAudioPlayer
  • 如何使工作Timer无效
  • 如何stop AVAudioPlayer何时可以重新使用
  • 如何停止转换

请尝试:

class FirstViewController: UIViewController {

    var player: AVAudioPlayer? //### You should not instantiate unused objects

    var player2: AVAudioPlayer?

    var secondSoundTimer: Timer?

    private func startPlaying() {
        stopPlaying()

        player?.play()
        //### Using `Timer` is one way to achieve pause-like thing.
        //### If you need to target older iOSs than 10.0, you need to modify this part.
        secondSoundTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) {timer in
            self.player2?.play()
            self.secondSoundTimer?.invalidate()
            self.secondSoundTimer = nil
        }
    }

    private func stopPlaying() {
        secondSoundTimer?.invalidate()
        secondSoundTimer = nil
        if let player = player, player.isPlaying {
            //### Stop playing (keeping internal `prepared` state) and rewind to the first place.
            player.pause()
            player.currentTime = 0
        }
        if let player2 = player2, player2.isPlaying {
            player2.pause()
            player2.currentTime = 0
        }
    }

    @IBOutlet weak var play: UIButton!
    @IBOutlet weak var play2: UIButton!

    var buttonActive = false

    @IBAction func pPressed(_ sender: Any) {
        startPlaying()
        if buttonActive {
            play.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
        } else {
            play.setBackgroundImage(UIImage(named: "Switch-Icon-40"), for: .normal)
        }
        buttonActive = !buttonActive
    }

    //### Don't you need `button2Active`?

    @IBAction func p2Pressed(_ sender: Any) {
        startPlaying()
        if buttonActive {
            play2.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
        } else {
            play2.setBackgroundImage(UIImage(named: "Switch-Icon-40"), for: .normal)
        }
        buttonActive = !buttonActive
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        play.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)
        play2.setBackgroundImage(UIImage(named: "SwitchD-Icon-40"), for: .normal)

        do {
            //### You can get URL directly from Bundle
            //### It's better to apply forced-unwrapping as soon as possible, if you need it eventually.
            let audioURL = Bundle.main.url(forResource: "DTMF-1", withExtension: "mp3")!
            player = try AVAudioPlayer(contentsOf: audioURL)
            //### `prepareToPlay()` improves response for the first play.
            player?.prepareToPlay()

            let audioURL2 = Bundle.main.url(forResource: "DTMF-2", withExtension: "mp3")!
            player2 = try AVAudioPlayer(contentsOf: audioURL2)
            player2?.prepareToPlay()
        } catch {
            print(error)
            //... or any other things you need...
        }

        //...
    }

    //### Stop playing on transition to other ViewConrollers.
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        stopPlaying()
    }
}