2017-09-20 15 views
0

私はint Sなど(000〜999)999番号を持っている、と彼らはすべてのUILabelに印刷されている、私もUILabelの値がupdateCurrentValueとして更新されますと、すべての数字が発表されなければなりません私は発表functionを行うことUIButtonを押すと、数字の音がAVFoundationと(例えば)発表のためのコードを介してインポートされた数15は以下のとおりです。スウィフト:多機能の問題

if currentValue == 15 { 
Sound15?.play() 
} 

は、今私がそのコードを探していますすべての999の番号のためにfunctionを作ることは時間の無駄になるので、何百ものために容易になります。何百というもののvalueしか与えられていないのですが、自動的に残りの数字はfuncになります。私は誰かが答えることができるように十分に明確にすることができることを願っています。これまで私がこれまでに持っていたことは次のとおりです。

import UIKit 
import AVFoundation 

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { 

var Sound1:AVAudioPlayer? 
var Sound2:AVAudioPlayer? 
var Sound3:AVAudioPlayer? 
var Sound4:AVAudioPlayer? 
var Sound5:AVAudioPlayer? 
var Sound6:AVAudioPlayer? 
var Sound7:AVAudioPlayer? 
var Sound8:AVAudioPlayer? 
var Sound9:AVAudioPlayer? 
var Sound10:AVAudioPlayer? 
var Sound11:AVAudioPlayer? 
var Sound12:AVAudioPlayer? 
var Sound13:AVAudioPlayer? 
var Sound14:AVAudioPlayer? 
var Sound15:AVAudioPlayer? 
var Sound16:AVAudioPlayer? 
var Sound17:AVAudioPlayer? 
var Sound18:AVAudioPlayer? 
var Sound19:AVAudioPlayer? 
var Sound20:AVAudioPlayer? 
var Sound30:AVAudioPlayer? 
var Sound40:AVAudioPlayer? 
var Sound50:AVAudioPlayer? 
var Sound60:AVAudioPlayer? 
var Sound70:AVAudioPlayer? 
var Sound80:AVAudioPlayer? 
var Sound90:AVAudioPlayer? 
var Sound100:AVAudioPlayer? 
var Sound200:AVAudioPlayer? 
var Sound300:AVAudioPlayer? 
var Sound400:AVAudioPlayer? 
var Sound500:AVAudioPlayer? 
var Sound600:AVAudioPlayer? 
var Sound700:AVAudioPlayer? 
var Sound800:AVAudioPlayer? 
var Sound900:AVAudioPlayer? 

var currentValue = 0 

func updateCurrentValue() { 
    let hundreds = max(0, pickerView.selectedRow(inComponent: 0)) 
    let tens = max(0, pickerView.selectedRow(inComponent: 1)) 
    let ones = max(0, pickerView.selectedRow(inComponent: 2)) 

    currentValue = hundreds * 100 + tens * 10 + ones 
} 

func numberOfComponents(in pickerView: UIPickerView) -> Int { 
    return 3 
} 

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
    return String(row) 
} 

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
return 10 // digits 0 - 9 
} 

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    updateCurrentValue() 

    changeLabelText() 
} 

//Some Functions as example of how it works: 

private func accouncingNumbers() { 

//for single digit 

if currentValue == 1 { 
Sound1?.play() 
} 

//for double digits 

if currentValue == 24 { 
Sound20?.play() 
SoundTimer = Timer.scheduledTimer(withTimeInterval: 1.2, repeats: false) {timer in 
    self.Sound4?.play() 
    self.SoundTimer?.invalidate() 
    self.SoundTimer = nil 
} 
} 

//for 3-digits 

if currentValue == 146 { 
Sound100?.play() 
SoundTimer = Timer.scheduledTimer(withTimeInterval: 1.2, repeats: false) {timer in 
    self.Sound40?.play() 
    self.SoundTimer?.invalidate() 
    self.SoundTimer = nil 
    self.SoundTimer = Timer.scheduledTimer(withTimeInterval: 1.2, repeats: false) {timer in 
     self.Sound6?.play() 
     self.SoundTimer?.invalidate() 
     self.SoundTimer = nil 
    } 
} 
} 

//Sounds imported here 

    do 

    { 
    let audioURL1 = Bundle.main.url(forResource: "1", withExtension: "mp3")! 
    Sound1 = try AVAudioPlayer(contentsOf: audioURL1) 
    Sound1?.prepareToPlay() 


    } 


    catch 

    { 
    print(error) 
    } 

} 

このプロセスでは、より簡単で短期間の方法を探しています。

+2

なぜあなたは1つ以上のオーディオプレーヤーを持っていますか? – rmaddy

+0

あなたのオーディオプレーヤーの作成方法と設定方法を示すコードを更新して、自分が行っていることを確認できます。 – rmaddy

+0

がコードを更新しました。 @rmaddy – Shahin

答えて

3

アプリケーションで束ねる必要があるサウンドファイルの量を最小限にするためには、あなたがこれに似たアルゴリズムをお勧めします:

func verbalizeValue(_ value: Int) { 
    let announcements = prepareAnnouncements(value) 
    playAnnouncements(announcements) 
} 

func prepareAnnouncements(_ value: Int) -> [String] { 
    var valueToProcess: Int = value 
    var announcements: [String] = [] 
    if valueToProcess >= 100 { 
     // values 100 and above 
     let hundred = valueToProcess/100 
     valueToProcess = valueToProcess % 100 
     let soundfile = "say_\(hundred)00.wav" 
     announcements.append(soundfile) 
    } 
    if valueToProcess >= 20 { 
     // values 30 to 99 
     let dozen = valueToProcess/10 
     valueToProcess = valueToProcess % 10 
     let soundfile = "say_\(dozen)0.wav" 
     announcements.append(soundfile) 
    } 
    if valueToProcess > 1 || announcements.count == 0 { 
     // values 0 to 19 
     let soundfile = "say_\(value).wav" 
     announcements.append(soundfile) 
    } 
    return announcements 
} 

func playAnnouncements(_ announcements: [String]) { 
    // announcements contains an array of wave filenames to play one after the other 
} 

あなたは、あなたがしてリロード単一AVAudioPlayerを使用することができます適切なウェーブファイル、再生開始、現在のサウンドが再生されたとき、次のウェーブファイルをキューにロードして、キューが空になるまで再生します。要求に応じて、再生を中止し、アナウンスキューをフラッシュする機能が必要な場合があります。

また、サポートされている範囲の1桁ごとにwaveファイルを作成し、say_0.mp3からsay_999に番号を付けます。 mp3;あなたがボタンを押すと、コンソールログに

// 
// ViewController.swift 
// SayNumber 
// 
// Created by Dave Poirier on 2017-09-21. 
// Copyright © 2017 Soft.io. All rights reserved. 
// 

import UIKit 
import AVFoundation 

class ViewController: UIViewController, AVAudioPlayerDelegate { 

    var valueToAnnonce: Int = 321 
    var audioPlayer: AVAudioPlayer! 
    var audioQueue: [String] = [] 

    @IBAction 
    func announceValue(_ sender: Any?) { 
     verbalizeValue(valueToAnnonce) 
    } 

    func verbalizeValue(_ value: Int) { 
     let announcements = prepareAnnouncements(value) 
     playAnnouncements(announcements) 
    } 

    func prepareAnnouncements(_ value: Int) -> [String] { 
     var valueToProcess: Int = value 
     var announcements: [String] = [] 
     if valueToProcess >= 100 { 
      // values 100 and above 
      let hundred = valueToProcess/100 
      valueToProcess = valueToProcess % 100 
      let soundfile = "say_\(hundred)00" 
      announcements.append(soundfile) 
     } 
     if valueToProcess >= 20 { 
      // values 30 to 99 
      let dozen = valueToProcess/10 
      valueToProcess = valueToProcess % 10 
      let soundfile = "say_\(dozen)0" 
      announcements.append(soundfile) 
     } 
     if valueToProcess >= 1 || announcements.count == 0 { 
      // values 0 to 19 
      let soundfile = "say_\(valueToProcess)" 
      announcements.append(soundfile) 
     } 
     return announcements 
    } 

    func playAnnouncements(_ announcements: [String]) { 
     // announcements contains an array of wave filenames to play one after the other 
     if nil != audioPlayer && audioPlayer!.isPlaying { 
      print("Audio player was active, stop it and play the new announcements!") 
      audioPlayer.stop() 
     } 
     audioQueue.removeAll() 
     for filename in announcements { 
      let path = pathForAudioFile(filename) 
      if path != nil { 
       audioQueue.append(path!) 
      } 
     } 
     playNextInQueue() 
    } 

    func playNextInQueue() { 
     let nextPathInQueue = audioQueue.first 
     if nextPathInQueue != nil { 
      audioQueue.removeFirst(1) 
      let audioFileURL = URL(fileURLWithPath: nextPathInQueue!) 
      audioPlayer = try? AVAudioPlayer(contentsOf: audioFileURL) 
      guard audioPlayer != nil else { 
       print("Oops, file not found: \(nextPathInQueue!)") 
       return 
      } 
      print("playing \(nextPathInQueue!)") 
      audioPlayer?.delegate = self 
      audioPlayer?.play() 
     } else { 
      print("looks like we are all done!") 
     } 
    } 

    func pathForAudioFile(_ filename: String) -> String? { 
     return Bundle.main.path(forResource: filename, ofType: "wav") 
    } 

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { 
     DispatchQueue.main.async { 
      self.playNextInQueue() 
     } 
    } 
} 

:あなたはより大きな数字(100万3百75688)

をサポートする起動する場合、本当に退屈な取得することはここで完全に動作する例です、次のように表示されている:

playing /var/containers/Bundle/Application/E2D5E7AD-26B4-4BBA-B52C-B91B62BA7161/SayNumber.app/say_300.wav 
playing /var/containers/Bundle/Application/E2D5E7AD-26B4-4BBA-B52C-B91B62BA7161/SayNumber.app/say_20.wav 
playing /var/containers/Bundle/Application/E2D5E7AD-26B4-4BBA-B52C-B91B62BA7161/SayNumber.app/say_1.wav 
looks like we are all done! 

コントローラは、オーディオファイルがsay_900するsay_100.wavから数百人のために、その後、say_90.wavするsay_20.wavからすべてのダースのために、その後、say_19.wavを通じて同じsay_0.wav期待しています。 wav。コードは、任意の長さのものに適応しやすいものでなければなりません。

+3

@ekscryptoが言う(投票された)ことに加えて、 'AVAudioPlayer'はデリゲートプロパティを持っていて、自分自身をデリゲートにして' audioPlayerDidFinishPlaying(_:successfully:) '関数を実装すると、以前のサウンドはタイマーを作成するのではなく完了する –

+0

残念ながら、私はこれらのアルゴリズムをどのように使用するかに慣れていません。アナウンサー関数のUIButton + UIButtonを設定することができれば、それはどのように動作するのでしょうか(私のコードに従う)、それはすばらしいでしょう。 @ekscrypto – Shahin

+0

@Shahin私は確かに学校の割り当てではないことを願っています! – ekscrypto