iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
ヒレガス本『Cocoa Programming for OS X (5th Edition)』のTableViewのサンプルをSwiftUIで実装してみた。
前回のSpeakLineはテキスト読み上げに利用する声をコードで求めていたが、今回のサンプルでは現在利用できる言語に対応した声から選択できるものとなる。
以下が、現在の言語で利用できる声のリストを返す関数。
func getVoices() -> [AVSpeechSynthesisVoice] {
let locale = Locale(identifier:Locale.preferredLanguages[0])
let voices = AVSpeechSynthesisVoice.speechVoices().filter { $0.language == locale.identifier }
return voices
}
得られた声のリストでListを作成する。
struct ContentView: View {
@State private var text = ""
@ObservedObject private var speaker: Speaker = .init()
private let voices = getVoices()
@State var selectedVoice: AVSpeechSynthesisVoice?
var body: some View {
VStack {
HStack {
ZStack(alignment: .topLeading) {
TextEditor(text: $text)
// prompt
if text.isEmpty {
Text("Enter text to be spoken...") .foregroundColor(Color.gray)
.padding(.horizontal, 6)
}
}
List(voices, id: \.self, selection: $selectedVoice) { voice in
Text(voice.name)
}
}
HStack {
Spacer()
Button("Stop") {
print("stop button clicked")
speaker.stop()
}.disabled(!speaker.isSpeaking)
Button("Speak") {
if text.isEmpty {
print("string from TextEditor is empty")
} else {
print("string is \(text)")
if let voice = selectedVoice {
print("voice is \(voice)")
speaker.speak(text, voice: voice)
} else {
speaker.speak(text)
}
}
}.disabled(speaker.isSpeaking)
}
}
.padding()
}
}
読み上げクラスも、声が渡された場合に対応。
final class Speaker: NSObject, AVSpeechSynthesizerDelegate, ObservableObject {
func speak(_ text: String, voice: AVSpeechSynthesisVoice) {
let utterance = AVSpeechUtterance(string: text)
utterance.voice = voice
speechSynth.speak(utterance)
}
}