You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何向视图传递可选函数作为参数?

SwiftUI 实现支持可选自定义动作的 YesOrNoView

你不需要用泛型来实现这个需求,直接给视图添加一个可选的逃逸闭包作为自定义动作参数即可,这是SwiftUI处理这类场景的常规做法。

正确的视图实现

struct YesOrNoView: View {
    @Binding var questionAnswer: Bool
    @Binding var questionsAnswered: Int
    // 可选自定义动作,默认值为nil,@escaping标记闭包会在视图生命周期外执行
    var customAction: (() -> Void)?
    
    var body: some View {
        HStack(spacing: 20) {
            Button("是") {
                questionAnswer = true
                questionsAnswered += 1
                // 仅当存在自定义动作时执行
                customAction?()
            }
            .buttonStyle(.borderedProminent)
            
            Button("否") {
                questionAnswer = false
                questionsAnswered += 1
                customAction?()
            }
            .buttonStyle(.bordered)
        }
    }
}

为什么你之前的泛型写法会出错

你尝试的<Content: Action>写法不成立,因为Swift标准库和SwiftUI里并没有名为Action的内置协议,这是混淆了UIKit的概念。而无约束的泛型<Content>会让Swift无法推断Content的具体类型——你并没有在视图中使用这个泛型参数,自然会报错。

使用示例

  • 普通题目(无需自定义动作):直接传入绑定参数即可
// 假设你在父视图中定义了对应的绑定变量
@State private var currentAnswer = false
@State private var answeredCount = 0

// 调用YesOrNoView
YesOrNoView(questionAnswer: $currentAnswer, questionsAnswered: $answeredCount)
  • 最后一题(需要自定义跳转逻辑):传入闭包实现自定义动作
// 假设父视图有导航路径绑定
@State private var navPath = NavigationPath()

// 调用时传入自定义跳转逻辑
YesOrNoView(questionAnswer: $finalAnswer, questionsAnswered: $answeredCount) {
    navPath.append(ResultView())
}

进阶:根据回答结果执行不同逻辑

如果你的自定义动作需要依赖用户选择的“是/否”结果,可以把闭包改成接受Bool参数:

// 修改视图的自定义动作参数
var customAction: ((Bool) -> Void)?

// 按钮中调用时传入当前回答
Button("是") {
    questionAnswer = true
    questionsAnswered += 1
    customAction?(questionAnswer)
}

Button("否") {
    questionAnswer = false
    questionsAnswered += 1
    customAction?(questionAnswer)
}

使用时可以根据回答分支处理:

YesOrNoView(questionAnswer: $finalAnswer, questionsAnswered: $answeredCount) { answer in
    if answer {
        navPath.append(SuccessView())
    } else {
        navPath.append(FailureView())
    }
}

内容的提问来源于stack exchange,提问作者SwiftlySlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:55:22