首页 > 解决方案 > 如何根据 UIimageview 图像从一键播放声音

问题描述

我为孩子们开发了一个功能齐全的闪存卡应用程序。它有一个 UIImageView 循环通过 26 张卡片 (abcs) 通过手势点击和一个音乐按钮,将为每个图像播放声音。现在我有这个 100% 的工作,但声音在 IF 语句中播放,添加了额外的 400 行代码。

音乐按钮示例:

        if (imageView.image?.isEqual(UIImage(named: "card1")))! {
            do { audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: aSound))
                audioPlayer.play()
            } catch {
                print("Couldn't load sound file")
            }
        }
        else if (imageView.image?.isEqual(UIImage(named: "card2")))! {
            do { audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: bSound))
                audioPlayer.play()
            } catch {
                print("Couldn't load sound file")
            }
        }
        else if (imageView.image?.isEqual(UIImage(named: "card3")))! {
            do { audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: cSound))
                audioPlayer.play()
            } catch {
                print("Couldn't load sound file")
            }
        }

我知道我可以设置一个包含声音文件的声音数组,但是我如何将它绑定到卡上?我不能在资产图像上设置标签属性可以吗?

寻找一种方法来缩短我拥有的当前代码。

标签: swiftxcodeavaudioplayer

解决方案


这是我要去做的一种方式。尚未对其进行测试,但它应该可以让您到达那里。!我使用数组,但 Set 或 Dictionary 会起作用。

1)创建一个结构

struct Card {
    let soundURL: URL
    let image: UIImage
}

2)将所有卡片收集在一个数组中:

let cards: [Card] = {
    var collection = [Card]()
    let soundPaths: [String] = ["aSound", "bSound", "xSound", "zSound"]
    let cardNames: [String] = ["card1", "card2", "card25", "card26"]

    // array of all 26 urls
    var soundUrls: [URL] {
        var urls = [URL]()
        for path in soundPaths {
            urls.append(URL(fileURLWithPath: path))
        }
        return urls
    }

    // array of all 26 images
    var cardImages: [UIImage] {
        var images = [UIImage]()
        for name in cardNames {
            guard let image = UIImage(contentsOfFile: name) else { continue }
            images.append(image)
        }
        return images
    }

    // not the best approach but if you have sound and naming
    // in the order then:
    for idx in 0..<26 {
        let card = Card(soundURL: soundUrls[idx], image: cardImages[idx])
        collection.append(card)
    }

    return collection
}()

3)给UIImage添加一个扩展来播放声音:

extension UIImage {
    func playSound() {
        let card = cards.filter { $0.image == self }.first
        if card != nil {
            do {
                let audioPlayer = try AVAudioPlayer(contentsOf: card!.soundURL)
                audioPlayer.play()
            } catch {
                print("Couldn't load the sound file with error: \(error)")
            }
        }
    }
}

然后当你得到你的 imageView.image 时,你应该能够做到:

imageView.image?.playSound()

我再次没有对此进行测试,但我认为逻辑仍然成立。希望它可以提供帮助。


推荐阅读