2017-07-28 58 views
1

目前 - 我正在构建flashcard应用程序。该应用程序显示一个闪存卡阵列,用户可以左右滑动(下面的代码)正如您所看到的,有11个不同的图像阵列(每个阵列包含一组特定的单词),所有这些阵列加起来最后一个阵列。我有一个音频文件来连接每个图像。点击屏幕上的声音(声音文件数组),xcode和swift

问题 - 我想这样做,当用户点击屏幕上的音频文件将播放。例如,如果湖图像正在显示并且用户点击屏幕,那么将会播放该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) 
    } 
} 
} 

回答

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 
+0

我在我的代码中添加了修订版,并且出现了一些错误。因为我将每张卡片作为一个对象,所以不会让我从他们身上制作一个字符串。我也收到了预期的声明错误。我编辑了这个问题并发布了修改后的代码和错误。 –

+0

好吧,所以我把卡类放在一个单独的文件中。 Xcode告诉我没有AVPlayer这样的模块。同样在什么时候我应该插入单词[index] .playSound()?我不断收到错误“顶级不允许使用表达式”。另外,我为我的superviewdidload发现错误,说超级不能在类成员之外使用。谢谢 –

+0

谢谢。正如你从我的原始代码中看到的那样,这些单词被分组到了11个不同的列表中,然后每个列表都有一串单词,并在最后有active = true。这是因为我有一个设置页面来打开和关闭每个单词列表。我怎么能有11个不同的“itemList”,并有每个列表活动=真?因为现在它不再是一个字符串,每个列表中都有一串字。 –

0

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

例如。创建下面的类:

class Card: NSObject { 
    var image: UIImage 
    var soundUrl: String 

    init(image: UIImage, soundUrl: String) { 
    self.image = image 
    self.soundUrl = soundUrl 
    } 
} 

然后你就可以例如创建卡对象的数组:

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等。取决于您的需求。

+0

你的答案是正确的,还可以使用MVC架构,但我们仍然可以通过使用MVVm架构来改进答案 –

+0

@JaydeepVyas同意但让我们诚实。问这个问题的人听起来很低级。我认为我们不应该让答案复杂化。让它变得简单。 –

+0

你好,请检查我关于添加两个数组的问题。如果你能回答的话,有50个声望点的奖励。 –