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

SwiftUI报错:buildExpression要求ValueWidget遵循AccessibilityRotorContent

解决SwiftUI报错:Static method 'buildExpression' requires that 'ValueWidget' conform to 'AccessibilityRotorContent'

问题详情

报错信息:
Static method 'buildExpression' requires that 'ValueWidget' conform to 'AccessibilityRotorContent'

使用环境:macOS Sonoma + Xcode 15.0

相关代码

ContentView.swift

struct ContentView: View {
    var body: some View {
        
        let data = (1...100).map { "Item \($0)" }

        let columns = [
            GridItem(.adaptive(minimum: 80))
        ]
        
        let v: Double = -10.0

        ScrollView {
                   LazyVGrid(columns: columns, spacing: 20) {
                       ForEach(data, id: \.self) { item in
                           ValueWidget(name: item, value: v)
                           v = v + 0.5;
                       }
                   }
                   .padding(.horizontal)
               }
               .frame(maxHeight: 300)
    }
}

/*
#Preview {
    ContentView()
}*/
struct ValueWidget_Previews: PreviewProvider {
    static var previews: some View {
        ValueWidget(name: "Hello", value: 42.0)
    }
}

ValueWidget.swift

import SwiftUI

struct ValueWidget: View {
    var name: String
    var value: Double
    
    var body: some View {
        VStack {
            Text(String(format: "%.1f", value))
                .font(.system(size: 40))
                .fontWeight(.bold)
            .foregroundColor(Color.blue)
            Text(name)
        }
        .padding()
        .background()
        .cornerRadius(10)
        .fixedSize()
        .frame(width: 120.0, height: 70.0)
        .padding()
        .accessibilityLabel(Text("\(name), Wert: \(value)"))
    }
}

#Preview {
    ValueWidget(name: "Hello", value: 42.0)
}

已尝试方法:替换预览代码为ValueWidget_Previews,但问题未解决。

问题原因

Xcode给出的报错信息具有误导性,实际问题并非ValueWidget需要遵循AccessibilityRotorContent协议,而是在SwiftUI的View构建闭包(body)中直接修改了用let声明的不可变变量v。

SwiftUI的body要求是纯函数,不能包含副作用(比如修改外部变量),这种非法操作导致编译器抛出错误提示,但错误信息指向了无关的协议一致性问题。

解决方法

通过循环索引计算value,避免修改变量,具体修改步骤如下:

  1. 修改ForEach的遍历方式,同时获取索引和元素:
    将原来的ForEach(data, id: \.self) { item in改为ForEach(Array(data.enumerated()), id: \.element) { index, item in

  2. 根据索引计算对应的value值:
    将ValueWidget(name: item, value: v)改为ValueWidget(name: item, value: -10.0 + Double(index) * 0.5)

  3. 删除原来的let v: Double = -10.0和循环内的v = v + 0.5;语句

修改后的ContentView代码:

struct ContentView: View {
    var body: some View {
        
        let data = (1...100).map { "Item \($0)" }

        let columns = [
            GridItem(.adaptive(minimum: 80))
        ]

        ScrollView {
                   LazyVGrid(columns: columns, spacing: 20) {
                       ForEach(Array(data.enumerated()), id: \.element) { index, item in
                           ValueWidget(name: item, value: -10.0 + Double(index) * 0.5)
                       }
                   }
                   .padding(.horizontal)
               }
               .frame(maxHeight: 300)
    }
}

#Preview {
    ContentView()
}

这样修改后,既符合SwiftUI的纯函数要求,又能实现每个ValueWidget的value从-10.0开始每次递增0.5的需求,同时解决了报错问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:33:27