滑动钢琴键(swift / iOS)

时间:2017-08-26 03:51:35

标签: ios swift

我正在使用一个app(钢琴),它有一系列按钮,每个按钮都有不同的mp3。屏幕显示12个按钮(钢琴键),我希望用户能够播放单独的声音或在一对夫妇上滑动以听到多个声音。就像真正的钢琴一样。我已经看到很多应用程序都这样做,但是当用户快速滑过多个按钮时,我似乎遇到了问题。以相同的速度,其他应用程序将播放所有笔记,但我的将跳过一些。感谢您的任何帮助!这将使我的应用程序发挥重要作用!

关于此代码的几个快速说明:

- 我这里只有裸骨以节省空间

- 我只是展示了6个音频播放器,但你明白了

- locationInNote1 ... Note2 ... Note3只是显示6这里保存位置,但你明白了

- "备注1"在按钮动作中是一个字符串,当用户选择播放不同的八度音程时可以改变,但它只是#,所以音频文件最终是1.mp3,2.mp3等。

- 按钮动作playNote1与其他按钮动作相同,所以我并没有在那里重复它们。

var audioPlayer = AVAudioPlayer()
var audioPlayer2 = AVAudioPlayer()
var audioPlayer3 = AVAudioPlayer()
var audioPlayer4 = AVAudioPlayer()
var audioPlayer5 = AVAudioPlayer()
var audioPlayer6 = AVAudioPlayer()

func playNote(for locationInView: CGPoint) {
    let locationInNote1 = note1Button.convert(locationInView, from: view)
    let locationInNote2 = note2Button.convert(locationInView, from: view)
    let locationInNote3 = note3Button.convert(locationInView, from: view)
    let locationInNote4 = note4Button.convert(locationInView, from: view)
    let locationInNote5 = note5Button.convert(locationInView, from: view)
    let locationInNote6 = note6Button.convert(locationInView, from: view)

    if note1Button.point(inside: locationInButton1, with: nil) {
        playNote1(self)
    }

    if note2Button.point(inside: locationInButton2, with: nil) {
        playNote2(self)
    }

    if note3Button.point(inside: locationInButton3, with: nil) {
        playNote3(self)
    }

    if note4Button.point(inside: locationInButton4, with: nil) {
        playNote4(self)
    }

    if note5Button.point(inside: locationInButton5, with: nil) {
        playNote5(self)
    }

    if note6Button.point(inside: locationInButton6, with: nil) {
        playNote6(self)
    }
}

@IBAction func playNote1(_ sender: Any) {
  let note1mp3 = note1
        if let path = Bundle.main.path(forResource: note1mp3, ofType: "mp3") {
            let url = URL(fileURLWithPath: path)
            do {
                audioPlayer = try AVAudioPlayer(contentsOf: url)
                audioPlayer.prepareToPlay()
                audioPlayer.play()
            }
            catch {
                print(error)
            }    
        }
}

 override func viewDidLoad() {
    super.viewDidLoad()

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
    view.addGestureRecognizer(panGesture)

1 个答案:

答案 0 :(得分:1)

这是一种有希望的方式:

  • 改进您的代码
  • 让您的代码更简单
  • 解决您遇到的问题

在这个例子中,我只放了3个音频播放器。 我会尽量让它尽可能直接......

import UIKit

class MyViewController: UIViewController {
    var audioPlayer = AVAudioPlayer()
    var audioPlayer2 = AVAudioPlayer()
    var audioPlayer3 = AVAudioPlayer()
    @IBOutlet var notes: [UIButton]!
    let references = [note1, note2, note3]

    @IBAction func notePressed(_ sender: UIButton) {
        play(note: notes.index(of: sender)! + 1)
    }

    func play(note: Int) {
        let reference = references[note - 1]
        if let path = Bundle.main.path(forResource: reference, ofType: "mp3") {      
            let url = URL(fileURLWithPath: path)
            do {
                audioPlayer = try AVAudioPlayer(contentsOf: url)
                audioPlayer.prepareToPlay()
                audioPlayer.play()
            }
            catch {
                print(error)
            }
        }
    }
}

解释

@IBOutlet var notes:[UIButton]!
这是一个 Outlet Collection 按钮。要进行此操作,请连接按钮,但选择插座集,而不是插座。确保按顺序连接每个按钮(1,2,3),否则会中断!

让引用= [note1,note2,note3]
这是对每个注释文件的引用数组。这样我们只需要一个功能来播放音符。

@IBAction func notePressed(_:sender :)
按钮调用此函数。对于每个按钮,连接触摸拖动输入(用于沿着音符滑动)和触摸操作。如果需要,您可以添加其他的。这些功能会比较发件人备注Outlet Collection 以找出按下了哪个音符,然后将其传递给 func play(:note :) 功能。

func play(:note :)
此功能获取音符编号,并播放相应的文件。它几乎与原始的相同,但它没有固定的音符,而是有一个由 @IBAction func notePressed(_:sender :) 方法传递的音符。

我希望这很有帮助,祝你好运!