将字符串传递给 SwiftUI 中附加到按钮的操作

Passing string to action attached to button in SwiftUI

我正在尝试将文本字段中的字符串传递到按钮操作中。这段代码的重点是获取输入的短语并大声说出来。当我 运行 带有静态文本的代码时,我得到了想要的结果(即大声朗读静态文本)。但是,当我尝试修改我的代码以传递键入的文本时,我不断收到一条错误消息,指出“()”不可转换为“() -> Void”。我不确定错误在哪里。

有效的原始代码

import SwiftUI
import AVFoundation

struct ContentView: View {

    @State var text: String = ""
    var body: some View {
        VStack {
            TextField("Enter Text Here", text: $text)
            Text(text)
            Button(action: Speek) {
            Text("Speek")
            }
        }

    }
}

func Speek {
    let utterance = AVSpeechUtterance(string: "This is a test")
    utterance.voice = AVSpeechSynthesisVoice(language: "en-US")

    let synthesizer = AVSpeechSynthesizer()
    synthesizer.speak(utterance)
}

产生错误的代码

import SwiftUI
import AVFoundation

struct ContentView: View {

    @State var text: String = ""
    var body: some View {
        VStack {
            TextField("Enter Text Here", text: $text)
            Text(text)
            Button(action: Speek(phrase: text)) {
            Text("Speek")
            }
        }

    }
}

func Speek (phrase: String) {
    let utterance = AVSpeechUtterance(string: phrase)
    utterance.voice = AVSpeechSynthesisVoice(language: "en-US")

    let synthesizer = AVSpeechSynthesizer()
    synthesizer.speak(utterance)
}

非常。事实上,您 不需要 通过它 - 您已经通过了!这是有效的代码:

struct ContentView: View {

    @State var text: String = ""
    var body: some View {
        VStack {
            TextField("Enter Text Here", text: $text)
            Text(text)
            Button(action: {
                self.speak()
            }) {
                HStack {
                    Image(systemName:"faceid").font(Font.body.weight(.bold))
                    Text("Speak").font(Font.body.weight(.bold))
                }.frame(width: 150)
            }
        }
    }
    func speak () {
        let utterance = AVSpeechUtterance(string: text)
        utterance.voice = AVSpeechSynthesisVoice(language: "en-US")

        let synthesizer = AVSpeechSynthesizer()
        synthesizer.speak(utterance)
    }
}
  • 我所做的唯一相关更改是删除函数和调用中所有 phrase 的痕迹,并仅使用 text。我可能做了第二个相关更改,因为您发布的代码没有明确说明该函数应该是 ContentView.
  • 的一部分
  • 我冒昧地 (a) 将您的函数名称从 "Speek" 更改为 "Speak" - 因为您使用的是 en-US 我认为正确的拼写看起来会更好,并且 (b)正确命名函数名称 "camel-case",因为这是大多数 Swift 代码的名称。

最后,关于我上面的代码的最后一个建议 - 将 speak 移动到 ObservableObject(基本上是 class and/or 您的模型)并将其公开为一个 EnvirronmentObject。您在那里完成的工作相当多,包括从您的 UI.

中删除功能代码 (speak)

尝试

Button(action: { Speek(phrase: text) } ) 

// 注意函数名要小写开头

虽然 @dfd 确实给出了答案,但它并没有解释为什么你的代码不起作用以及为什么他现在可以。

Buttons 动作取函数。在您的第一个案例中,您将函数 Speak 传递给它。它的类型为 () -> Void,这意味着它没有参数并且 returns 没有值。

在您的错误情况下,您正在调用该函数,因此该函数调用的结果将作为 action: 的参数传递。正如我刚才提到的,Speak 函数的结果是 Void.

另外很高兴知道 Void() 的别名。