2017-08-26 1 views
0

Ich arbeite an einer App (Piano), die eine Reihe von Tasten hat, die jeweils eine andere mp3 hat. Der Bildschirm zeigt 12 Tasten (Klaviertasten) und ich möchte, dass der Benutzer in der Lage ist, einen einzelnen Ton zu spielen oder über ein Paar zu wischen, um mehrere zu hören. Genau wie ein echtes Klavier. Ich habe schon viele Apps gesehen, aber meiner scheint ein Problem zu haben, wenn der Benutzer schnell über mehrere Tasten gleitet. Mit derselben Geschwindigkeit spielen andere Apps alle Noten, aber meine werden einige überspringen. Danke für jede Hilfe! Dies wird den Unterschied in meiner App machen!Sliding über Klaviertasten (swift/iOS)

Ein paar schnelle Notizen zu diesem Code:

-Ich habe nur die nackten hier Knochen um Platz zu sparen

-I nur 6 Audio-Player zeigte, aber Sie bekommen die Idee

-das locationInNote1 ... Note2 ... Note3 zeigt nur 6 hier, um Platz zu sparen, aber Sie erhalten die Idee

- "Note1" in der Schaltfläche Aktion ist eine Zeichenfolge, die geändert werden kann, wenn der Benutzer verschiedene Oktaven zur Wiedergabe auswählt von, aber es ist nur ein #, so die Audio-Dateien ut imately sind 1.mp3, 2.mp3, etc.

-die Schaltfläche Aktion PlayNote1 ist das gleiche wie die anderen Tastenaktionen, so dass ich sie nicht alle dort wiederholen.

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

FYI - Verwenden Sie 'if/else' in Ihrer' playNote' Methode, da ein Punkt immer nur in einer Schaltfläche sein kann. – rmaddy

+0

Warum laden Sie jedes MP3 aus dem Bundle und erstellen jedes Mal einen neuen Audioplayer, wenn eine Note abgespielt werden soll? Das ist sehr ineffizient. – rmaddy

+0

Warum haben Sie 6 doppelte 'playNoteX' Methoden? Einfach eins und die Notennummer übergeben, damit auf die richtige mp3-Datei zugegriffen werden kann. – rmaddy

Antwort

0

Hier ist ein Weg, um hoffentlich:

  • Code verbessern
  • Machen Sie Ihren Code einfacher
  • das Problem zu beheben sind Sie

In diesem Beispiel ist, Ich werde nur 3 Audio-Player setzen. Ich werde versuchen, es so einfach wie möglich zu machen ...

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) 
      } 
     } 
    } 
} 

Erklärung

@IBOutlet var Anmerkungen: [UIButton]!
Dies ist eine Outlet Collection von Tasten. Um dies zu machen, schließen Sie eine Taste, aber wählen Sie Outlet Collection statt nur Outlet. Stellen Sie sicher, dass Sie jede Taste in Reihenfolge (1, 2, 3) verbinden, sonst wird es brechen!

lassen Referenzen = [note1, note2, Anmerkung3]
Dies ist eine Reihe von Verweisen auf jede der Notiz Dateien. Dies ist so, dass wir nur eine Funktion benötigen, um eine Note zu spielen.

@IBAction func notePressed (_: Absender :)
Diese Funktion wird durch die Tasten aufgerufen wird. Für jede Taste, verbinden Sie die Touch Drag Geben Sie (zum Verschieben von Notizen) und Touch Down Aktionen. Sie können andere hinzufügen, wenn Sie möchten.Die Funktionen vergleicht die Absender und Hinweise Outlet Collection um herauszufinden, welche Note gedrückt wurde, dann übergibt es an die Func Play (: Hinweis :) Funktion.

func play (: note :)
Diese Funktion nimmt die Notennummer und spielt die entsprechende Datei. Es ist fast identisch mit Ihrem Original, aber anstelle einer festen Notiz hat es eine, die von der Methode @IBAction func notePressed (_: sender :) übergeben wird.

Ich hoffe, das ist hilfreich, viel Glück!