LoginSignup
10
9

More than 5 years have passed since last update.

ヒレガス本の例題を Swift で書いてみる(2)

Posted at

第5章「ターゲットとアクション」〜第6章「ヘルパオブジェクト」で取り上げられている「SpeakLine」アプリケーションを Swift で書いてみる。プログラムは NSSpeechSynthesizer を利用して入力したテキストを音声で読み上げるというもの。音声による読み上げ自体は NSSpeechSynthesizer#startSpeakingString にテキストを渡すだけなので特に難しいことは何もない。例題の目標は View と Controller を IBOutletIBAction で接続する方法、デリゲートやプロトコルの利用法についての学習。

ソース:https://github.com/hugo-sb/Hillegass-ch5-6

スクリーンショット 2014-11-04 22.15.06.png

以下、プログラムを書いていて引っかかった場所。

InitialFirstRespoder の設定

書籍では WindowInitialFirstRespoderText Field を結びつけて、起動時に Text Field がフォーカスを取得するように設定することになっているが、今回は Storybord を利用しているため、その方法を利用することができず、また、Storybord も良く理解できていないので代替の方法も判らない。とりあえず、デフォルトの状態で Text Field がフォーカスを取得しているので、この件は今後の課題とする。

文字列の長さを取得する方法

NSString には Length という文字列長を取得するメソッドが存在したが、Swift の String には同様のメソッドは存在しないようだ。

ios - Get the length of a String - Stack Overflow

上記、リンク先によると

sample
var length = countElements("test")

で取得できるとのこと。

ViewController.swift のソースは以下の通り。

ViewController.swift
import Cocoa

class ViewController: NSViewController, NSSpeechSynthesizerDelegate {

    @IBOutlet weak var textField: NSTextField!
    @IBOutlet weak var stopButton: NSButton!
    @IBOutlet weak var speakButton: NSButton!
    @IBOutlet weak var tableView: NSTableView!

    let speechSynth = NSSpeechSynthesizer()
    let voiceList = NSSpeechSynthesizer.availableVoices()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        speechSynth.delegate = self

        let defaultVoice = NSSpeechSynthesizer.defaultVoice()
        for i in (0...voiceList!.count)
        {
            if (voiceList![i] as NSString) == defaultVoice
            {
                tableView.selectRowIndexes(NSIndexSet(index: i), byExtendingSelection: false)
                tableView.scrollRowToVisible(i)
                break
            }
        }
    }

    override var representedObject: AnyObject? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func sayIt(sender: AnyObject) {
        var str = textField.stringValue
        if countElements(str) > 0
        {
            speechSynth.startSpeakingString(str)
            NSLog("Have started to say: \(str)")
            stopButton.enabled = true
            speakButton.enabled = false
            tableView.enabled = false
        }
        else
        {
            NSLog("string from %@ is of zero-length", textField)
        }
    }

    @IBAction func stopIt(sender: AnyObject) {
        speechSynth.stopSpeaking()
        NSLog("stopping")
    }

    func speechSynthesizer(sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool)
    {
        stopButton.enabled = false
        speakButton.enabled = true
        tableView.enabled = true
    }

    func numberOfRowsInTableView(aTableView: NSTableView) -> Int
    {
        return voiceList!.count
    }

    func tableView(aTableView: NSTableView,
        objectValueForTableColumn aTableColumn: NSTableColumn?,
        row rowIndex: Int) -> AnyObject?
    {
        let v = voiceList![rowIndex] as NSString
        let dict = NSSpeechSynthesizer.attributesForVoice(v)
        return dict![NSVoiceName]
    }

    func tableViewSelectionDidChange(aNotification: NSNotification)
    {
        let row = tableView.selectedRow
        if row >= 0
        {
            let selectedVoice = voiceList![row] as String
            speechSynth.setVoice(selectedVoice)
            NSLog("New voice: \(selectedVoice)")
        }
    }
}

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9