【问题标题】:Tap screen for sound(array of sound files), xcode and swift点击屏幕获取声音(声音文件数组)、xcode 和 swift
【发布时间】:2017-07-28 22:48:12
【问题描述】:

目前 - 我正在构建一个抽认卡应用程序。该应用程序显示一组闪存卡,用户可以左右滑动(代码如下)正如您所见,有 11 个不同的图像数组(每个包含一组特定的单词),所有这些数组加起来就是一个最终的大批。我有一个音频文件来耦合每个图像。

问题 - 我想让它在用户点击屏幕时播放音频文件。例如,如果正在显示湖图像并且用户点击屏幕,则将播放lake.mp4 音频文件,如果用户向左滑动小羊图像并点击屏幕,则将播放lamb.mp4 音频文件等。 . 我知道我必须添加一个轻击手势识别器,但我不确定如何让每个音频文件耦合正确的图像。

下面的代码是我目前正在使用的。

import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {

@IBAction func home(_ sender: Any) {
    performSegue(withIdentifier: "home", sender: self)
}

@IBOutlet weak var imgPhoto: UIImageView!

struct List {
    let words: [String]
    var active: Bool
}

let list1 = List(words:["lake", "lamb", "lamp", "lark", "leaf", "leash", "left", "leg", "lime", "lion", "lips", "list", "lock", "log", "look", "love", "lunch"], active: true)

let list2 = List(words: ["ladder", "ladybug", "laughing", "lawnmower", "lemon", "leopard", "leprechaun", "letters", "licking", "lifesaver", "lifting", "lightbulb", "lightning", "listen", "llama"], active: true)

let list3 = List(words: ["alligator", "balance", "ballerina", "balloon", "bowling", "cello", "colors", "curlyhair", "dollar", "dolphin", "elephant", "eyelashes", "gasoline", "goalie", "hula", "jellyfish", "olive", "pillow", "pilot", "polarbear", "rollerskate", "ruler", "silly", "telephone", "television", "tulip", "umbrella", "valentine", "violin", "xylophone", "yellow"], active: true)

let list4 = List(words: ["apple", "ball", "bell", "bubble", "castle", "fall", "fishbowl", "girl", "owl", "pail", "peel", "pool", "smile", "whale", "wheel"], active: true)

let list5 = List(words: ["planet", "plank", "plant", "plate", "play", "plum", "plumber", "plus"], active: true)

let list6 = List(words: ["black", "blanket", "blender", "blocks", "blond", "blood", "blow", "blue"], active: true)

let list7 = List(words: ["flag", "flipflop", "float", "floor", "flower", "fluffy", "flute", "fly"], active: true)

let list8 = List(words: ["glacier", "glad", "glasses", "glide", "glitter", "globe", "glove", "glue"], active: true)

let list9 = List(words: ["clam", "clamp", "clap", "claw", "clean", "climb", "clip", "cloud"], active: true)

let list10 = List(words:["sled", "sleep", "sleeves", "slice", "slide", "slime", "slip", "slow"], active: true)

let list11 = List(words: ["belt", "cold", "dolphin", "elf", "golf", "melt", "milk", "shelf"], active: true)

var imageIndex: Int = 0

var imageList: [String] {

    let wordLists = [list1, list2, list3, list4, list5, list6, list7, list8, list9, list10, list11]



    let active = wordLists.reduce([]) { (result:[String], list:List) in
        if list.active {
            return result + list.words

        } else {
            return result
        }
    }

    return active

}




override func viewDidLoad() {
    super.viewDidLoad()

    imgPhoto.image = UIImage(named: imageList[imageIndex])

    // Do any additional setup after loading the view.
    imgPhoto.isUserInteractionEnabled = true

    let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    leftSwipe.cancelsTouchesInView = false

    let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    rightSwipe.cancelsTouchesInView = false

    leftSwipe.direction = .left
    rightSwipe.direction = .right

    view.addGestureRecognizer(leftSwipe)
    view.addGestureRecognizer(rightSwipe)

}

func Swiped(gesture: UIGestureRecognizer) {

    if let swipeGesture = gesture as? UISwipeGestureRecognizer {

        switch swipeGesture.direction {

        case UISwipeGestureRecognizerDirection.right :
            print("User swiped right")

            // decrease index first

            imageIndex -= 1

            // check if index is in range

            if imageIndex < 0 {

                imageIndex = imageList.count - 1

            }

            imgPhoto.image = UIImage(named: imageList[imageIndex])

        case UISwipeGestureRecognizerDirection.left:
            print("User swiped Left")

            // increase index first

            imageIndex += 1

            // check if index is in range

            if imageIndex > imageList.count - 1 {

                imageIndex = 0

            }

            imgPhoto.image = UIImage(named: imageList[imageIndex])

        default:
            break //stops the code/codes nothing.
        }
    }
}
}

   import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {



var imageIndex: Int = 0
@IBAction func home(_ sender: Any) {
    performSegue(withIdentifier: "home", sender: self)
}

@IBOutlet weak var imgPhoto: UIImageView!


let itemList:[Card] = [
    Card(image: UIImage(named: "alligator")!, soundUrl: "Alligator.m4a"),
    Card(image: UIImage(named: "apple")!, soundUrl: "Apple.m4a"),
    Card(image: UIImage(named: "ball")!, soundUrl: "Ball.m4a")
]



override func viewDidLoad() {
    super.viewDidLoad()


    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    imgPhoto.isUserInteractionEnabled = true
    imgPhoto.addGestureRecognizer(tapGestureRecognizer)

    imgPhoto.image = (itemList[0] ).image

    // Do any additional setup after loading the view.
    imgPhoto.isUserInteractionEnabled = true

    let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    leftSwipe.cancelsTouchesInView = false

    let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
    rightSwipe.cancelsTouchesInView = false

    leftSwipe.direction = .left
    rightSwipe.direction = .right


    view.addGestureRecognizer(leftSwipe)
    view.addGestureRecognizer(rightSwipe)

}

func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{

    itemList[imageIndex].playSound()
    // Your action
}

func Swiped(gesture: UIGestureRecognizer) {

    if let swipeGesture = gesture as? UISwipeGestureRecognizer {

        switch swipeGesture.direction {

        case UISwipeGestureRecognizerDirection.right :
            print("User swiped right")

            // decrease index first

            imageIndex -= 1

            // check if index is in range

            if imageIndex < 0 {

                imageIndex = itemList.count - 1

            }

            imgPhoto.image = itemList[imageIndex].image

        case UISwipeGestureRecognizerDirection.left:
            print("User swiped Left")
            // increase index first

            imageIndex += 1

            // check if index is in range

            if imageIndex > itemList.count - 1 {

                imageIndex = 0

            }



            imgPhoto.image = itemList[imageIndex].image
        default:


            break //stops the code/codes nothing.
        }
    }
}
}

import Foundation; import UIKit; import AVFoundation


class Card: NSObject
{
var image: UIImage
var soundUrl: String
var player: AVAudioPlayer?

init(image: UIImage, soundUrl: String) {
    self.image = image
    self.soundUrl = soundUrl
}
    func playSound()
{
    guard let url = Bundle.main.url(forResource: self.soundUrl, withExtension: "m4a") else { return }
    do
    {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        player = try AVAudioPlayer(contentsOf: url)
        guard let player = player else { return }
        player.play()
    print("hhh")
    } catch let error {
        print(error.localizedDescription)
    }
}
}

【问题讨论】:

    标签: ios arrays swift xcode uitapgesturerecognizer


    【解决方案1】:

    更多格式化结构使用MMVM架构的建模概念

    import AVFoundation
    
            class Card: NSObject 
            {
              var image: UIImage
              var soundUrl: String
              var player: AVAudioPlayer?
    
              init(image: UIImage, soundUrl: String) {
                self.image = image
                self.soundUrl = soundUrl
              }
    
    
            func playSound() 
            {
                guard let url = Bundle.main.url(forResource: self.soundUrl, withExtension: "mp3") else { return }
                do 
                {
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
                    try AVAudioSession.sharedInstance().setActive(true)
    
                    player = try AVAudioPlayer(contentsOf: url)
                    guard let player = player else { return }
    
                    player.play()
                } catch let error {
                    print(error.localizedDescription)
                }
            }
            }
    

    用法

     class SecondViewController: UIViewController , UIGestureRecognizerDelegate  {
    
    
    
        var imageIndex: Int = 0
        @IBAction func home(_ sender: Any) {
            performSegue(withIdentifier: "home", sender: self)
        }
    
        @IBOutlet weak var imgPhoto: UIImageView!
    
    
        let itemList:[Card] = [
            Card(image: UIImage(named: "lake")!, soundUrl: "lake.mp3"),
            Card(image: UIImage(named: "river")!, soundUrl: "river.mp3"),
            Card(image: UIImage(named: "ocean")!, soundUrl: "ocean.mp3")
            ]
    
    
    
        override func viewDidLoad() {
    
    super.viewDidLoad()
    
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    imgPhoto.isUserInteractionEnabled = true
    imgPhoto.addGestureRecognizer(tapGestureRecognizer)
    
    
    
    
            imgPhoto.image = (itemList[0] as! Card).image
    
            // Do any additional setup after loading the view.
            imgPhoto.isUserInteractionEnabled = true
    
            let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
            leftSwipe.cancelsTouchesInView = false
    
            let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
            rightSwipe.cancelsTouchesInView = false
    
            leftSwipe.direction = .left
            rightSwipe.direction = .right
    
            view.addGestureRecognizer(leftSwipe)
            view.addGestureRecognizer(rightSwipe)
    
        }
    
    
          func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
    {
    
    itemList[imageIndex].playSound()
        // Your action
    }
        func Swiped(gesture: UIGestureRecognizer) {
    
            if let swipeGesture = gesture as? UISwipeGestureRecognizer {
    
                switch swipeGesture.direction {
    
                case UISwipeGestureRecognizerDirection.right :
                    print("User swiped right")
    
                    // decrease index first
    
                    imageIndex -= 1
    
                    // check if index is in range
    
                    if imageIndex < 0 {
    
                        imageIndex = imageList.count - 1
    
                    }
    
                    imgPhoto.image = itemList[imageIndex].image
    
                case UISwipeGestureRecognizerDirection.left:
                    print("User swiped Left")
    
                    // increase index first
    
                    imageIndex += 1
    
                    // check if index is in range
    
                    if imageIndex > imageList.count - 1 {
    
                        imageIndex = 0
    
                    }
    
                    imgPhoto.image = itemList[imageIndex].image
                default:
    
    
                    break //stops the code/codes nothing.
                }
            }
        }
    }
    

    你最后的疑惑解决方案

    let firstList:[Card] = [
            Card(image: UIImage(named: "lake")!, soundUrl: "lake"),
            Card(image: UIImage(named: "lamb")!, soundUrl: "lamb"),
            Card(image: UIImage(named: "lamp")!, soundUrl: "lamp")
               ]
    struct List {
        let words: [Card] /*Create array of cards*/
        var active: Bool
    }
    
    let list1 = List(words:firstList, active: true)
    let list2 = List(words:secondList, active: true)
    
     let wordLists = [list1, list2]
    
    print((wordLists[0] as! List).words[0].soundurl)
    
    **OUTPUT**
    lake
    

    【讨论】:

    • 我在我的代码中添加了修订并得到了一些错误。因为我将每张卡片都制作成一个对象,所以我不会用它们制作一个字符串。我也收到了预期的声明错误。我编辑了问题并发布了修改后的代码和错误。
    • 好的,所以我将卡片类放在一个单独的文件中。 Xcode 告诉我没有像 AVPlayer 这样的模块。我应该在什么时候插入 words[index].playSound()?我不断收到错误“表达式不允许在顶层”。我的 superviewdidload 也收到一个错误,说 super 不能在班级成员之外使用。谢谢
    • 谢谢。正如您从我的原始代码中看到的那样,单词被分组到 11 个不同的列表中,然后每个列表都有一个单词字符串,并且最后有 active = true。这是因为我有一个设置页面来打开和关闭每个单词列表。我怎样才能拥有 11 个不同的“itemList”并让每个列表处于活动状态 = true?因为现在它不再是一个字符串,之前每个列表都有一个单词字符串。
    • 好的,所以我只是用 3 张图像运行演示。该应用程序编译没有任何错误。当我运行应用程序时,我可以在图像中滑动,但单击时没有声音
    • 我没有添加任何点击手势。到目前为止,我已经制作了包含 func 播放声音的卡片类,并将修改后的代码添加到我的第二个视图控制器中。
    【解决方案2】:

    我建议使用对象数组而不是使用 2 个不同的数组。

    例如。创建以下类:

    class Card: NSObject {
      var image: UIImage
      var soundUrl: String
    
      init(image: UIImage, soundUrl: String) {
        self.image = image
        self.soundUrl = soundUrl
      }
    }
    

    然后您可以创建一个 Card 对象数组,例如:

    let cards = [
            Card(image: UIImage(named: "lake"), soundUrl: "lake.mp3"),
            Card(image: UIImage(named: "river"), soundUrl: "river.mp3"),
            Card(image: UIImage(named: "ocean"), soundUrl: "ocean.mp3")
        ]
    

    然后当用户滑动时使用数组cards 来访问图像或声音的url。数组的每个元素都是一个 Card,它有 2 个属性:UIImage 和 String(你的声音的 URL)。

    PS:模型只是一个例子,它可以是 UIImage + URL 等。取决于你的需要。

    【讨论】:

    • 你的答案是正确的,也使用了 MVC 架构,但我们仍然可以通过使用 MVVm 架构来改进答案
    • @JaydeepVyas 同意,但说实话。问这个问题的人听起来很初级。我认为我们不应该使答案复杂化。让它变得简单。
    • 你好,请检查我关于添加两个数组的问题。如果你能回答,有 50 点声望奖励。
    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多