質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.10%

swiftuiの画面からclass ViewController: UIViewControllerへの画面遷移方法

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 187

Yusuke_O

score 7

質問内容

下記コードについて、同じプロジェクト内のSwiftUIで構築した他ファイルから画面遷移する方法をご教示下さい

状況の説明

当方、iOSアプリの開発を勉強するため、XcodeでSwiftUIを触り始めた初学者です。
Swiftで音声認識を行うためのコードを参照先を下にエラーを解除しながら作成いたしました。
参照先:https://swift-ios.keicode.com/ios/speechrecognition-live.php

なんとか下記コードのエラーは全て解除したのですが、同じプロジェクト内のSwiftUIで構築した他ファイルからNavigationLink等を用いて、遷移する方法がわかりません。下記サイトなども参照し試しましたが、やはり遷移できませんでした。
https://qiita.com/papassan/items/5edf98e534b1c5d8808e

かれこれ3日間以上同じ所でつまづいている状態です。
初学者のため、質問が拙く伝わりづらい、もしくは情報不足な点などございましたらご指摘いただけますと幸いです。

なお、環境はXCode Ver11.5となります。

import UIKit
import Speech
import AVFoundation

class ViewController: UIViewController {

  var isRecording = false
  var w: CGFloat = 0
  var h: CGFloat = 0
  let d: CGFloat = 50
  let l: CGFloat = 28

  let recognizer = SFSpeechRecognizer(locale: Locale.init(identifier: "ja_JP"))!
  var audioEngine: AVAudioEngine!
  var recognitionReq: SFSpeechAudioBufferRecognitionRequest?
  var recognitionTask: SFSpeechRecognitionTask?

  @IBOutlet weak var recordButton: UIButton!
  @IBOutlet weak var baseView: UIView!
  @IBOutlet weak var outerCircle: UIView!
  @IBOutlet weak var innerCircle: UIView!
  @IBOutlet weak var textView: UITextView!

  override func viewDidLoad() {
    super.viewDidLoad()

    audioEngine = AVAudioEngine()
    textView.text = ""
  }

  override func viewDidAppear(_ animated: Bool) {

    w = baseView.frame.size.width
    h = baseView.frame.size.height

    initRoundCorners()
    showStartButton()

  SFSpeechRecognizer.requestAuthorization { (authStatus) in
    DispatchQueue.main.async {
      if authStatus != SFSpeechRecognizerAuthorizationStatus.authorized {
        self.recordButton.isEnabled = false
        self.recordButton.backgroundColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1)
      }
    }
  }
}

func stopLiveTranscription() {
  audioEngine.stop()
  audioEngine.inputNode.removeTap(onBus: 0)
  recognitionReq?.endAudio()
}

func startLiveTranscription() throws {

  // もし前回の音声認識タスクが実行中ならキャンセル
  if let recognitionTask = self.recognitionTask {
    recognitionTask.cancel()
    self.recognitionTask = nil
  }
  textView.text = ""

  // 音声認識リクエストの作成
  recognitionReq = SFSpeechAudioBufferRecognitionRequest()
  guard let recognitionReq = recognitionReq else {
    return
  }
  recognitionReq.shouldReportPartialResults = true

  // オーディオセッションの設定
  let audioSession = AVAudioSession.sharedInstance()
  try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
  try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
  let inputNode = audioEngine.inputNode

 // マイク入力の設定
  let recordingFormat = inputNode.outputFormat(forBus: 0)
  inputNode.installTap(onBus: 0, bufferSize: 2048, format: recordingFormat) { (buffer, time) in
    recognitionReq.append(buffer)
  }
  audioEngine.prepare()
  try audioEngine.start()

  recognitionTask = recognizer.recognitionTask(with: recognitionReq, resultHandler: { (result, error) in
    if let error = error {
      print("\(error)")
    } else {
      DispatchQueue.main.async {
        self.textView.text = result?.bestTranscription.formattedString
      }
    }
  })
}

@IBAction func recordButtonTapped(_ sender: Any) {
  if isRecording {
    UIView.animate(withDuration: 0.2) {
      self.showStartButton()
    }
    stopLiveTranscription()
  } else {
    UIView.animate(withDuration: 0.2) {
      self.showStopButton()
    }
    try! startLiveTranscription()
  }
  isRecording = !isRecording
}

  func initRoundCorners(){
    recordButton.layer.masksToBounds = true

    baseView.layer.masksToBounds = true
    baseView.layer.cornerRadius = 10
    baseView.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]

    outerCircle.layer.masksToBounds = true
    outerCircle.layer.cornerRadius = 31
    outerCircle.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)

    innerCircle.layer.masksToBounds = true
    innerCircle.layer.cornerRadius = 29
    innerCircle.backgroundColor = #colorLiteral(red: 0.1298420429, green: 0.1298461258, blue: 0.1298439503, alpha: 1)
  }

  func showStartButton() {
    recordButton.frame = CGRect(x:(w-d)/2,y:(h-d)/2,width:d,height:d)
    recordButton.layer.cornerRadius = d/2
  }

  func showStopButton() {
    recordButton.frame = CGRect(x:(w-l)/2,y:(h-l)/2,width:l,height:l)
    recordButton.layer.cornerRadius = 3.0
  }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる