swift 为什么我得到这个错误?错误:无法为表达式生成诊断;请提交bug报告

bvuwiixz  于 2023-10-15  发布在  Swift
关注(0)|答案(1)|浏览(102)

帮助这个观点。诊断不清楚,我不知道如何修复这个错误。

import SwiftUI

struct WeeklyView: View {
    @Binding var selectedDays: String
    @Binding var weekDays: [String]
    var body: some View {
        
        let days = Calendar.current.weekdaySymbols
        
        HStack(spacing: 8) {
            
            ForEach(weekDays, id: \.self) { day in
                let index = HabitEntity.weekDays.firstIndex { value in
                    return value == day
                } ?? -1
                ZStack {
                    Circle()
                        .fill(index != -1 ? Color(HabitEntity.habitColor) :
                                .customIndigoMedium.opacity(0.4))
                        .frame(width: 49, height: 49)
                        .opacity(0.4)
                    
                    Text(day.prefix(2))
                        .foregroundColor(Color.white)
                        .fontWeight(.semibold)
                        .padding(.vertical, 12)
                }
                .onTapGesture {
                    withAnimation {
                        if index !=  -1 {
                            HabitEntity.weekDays.remove(at: index)
                        } else {
                            HabitEntity.weekDays.append((day))
                        }
                    }
                }
            }
        }
    }
}

struct WeeklyView_Previews: PreviewProvider {
    static var previews: some View {
        WeeklyView(selectedDays: .constant())
    }
}

我经常遇到这个错误:无法为表达式生成诊断;请提交bug报告
我期待代码运行。

4xrmg8kj

4xrmg8kj1#

一般来说,你想最大限度地减少SwiftUI视图中的过程代码-在视图构建器中有很多隐藏的东西,它可能导致生成的表达式太复杂,编译器无法解析。当这种情况发生时,你会得到你看到的错误。
您还没有提供有关数据结构的所有信息,因此我创建了一些说明如何处理此问题的信息。(我怀疑你可能会回到Core Data,因为你有一个HabitEntity-我在这里没有考虑过)。
首先,为HabitEntity定义一个Weekday枚举和一个Observable对象。实体的可观察性很重要,因为您希望视图在weekdays更改时更新

import Foundation
import SwiftUI

enum Weekday: Int {
    case sunday = 0
    case monday = 1
    case tuesday = 2
    case wednesday = 3
    case thursday = 4
    case friday = 5
    case saturday = 6
    
    var shortSymbol: String {
        let calendar = Calendar(identifier: .gregorian)
        return calendar.shortWeekdaySymbols[self.rawValue]
    }
    
    static var orderedDays: [Weekday] {
        [.sunday,.monday,.tuesday,.wednesday,.thursday,.friday,.saturday]
    }
}

class HabitEntity: ObservableObject {
    var color: Color
    var name: String
    @Published var weekdays: Set<Weekday> = []
    
    init(name: String, color: Color) {
        self.name = name
        self.color = color
    }
    
}

这是我的简单ContentView-它只是创建一个单一的静态@StateObject HabitEntity,并将其传递给WeeklyView

struct ContentView: View {
    @StateObject var habit = HabitEntity(name:"Test", color:.blue)
    var body: some View {
        WeeklyView(habit: habit)
        .padding()
    }
}

这是我的WeeklyView实现

struct WeeklyView: View {
    @ObservedObject var habit: HabitEntity
    var body: some View {
        HStack(spacing: 8) {
            ForEach(Weekday.orderedDays, id: \.self) { day in
                ZStack {
                    Circle()
                        .fill(habit.weekdays.contains(day) ? habit.color :
                                .indigo.opacity(0.4))
                        .frame(width: 49, height: 49)
                        .opacity(0.4)
                    
                    Text(day.shortSymbol)
                        .foregroundColor(Color.white)
                        .fontWeight(.semibold)
                        .padding(.vertical, 12)
                }
                .onTapGesture {
                    withAnimation {
                        if habit.weekdays.contains(day) {
                            habit.weekdays.remove(day)
                        } else {
                            habit.weekdays.insert(day)
                        }
                    }
                }
            }
        }
    }
}

请注意,因为我对weekdays使用了Set<Weekday>,所以检查当前是否选择了工作日以及修改选择要简单得多。不需要关注index或sentinel值(-1)。
它还有助于SwiftUI拥有小的视图结构-抽象使其更容易跟踪正在发生的事情。
通过引入CirleDayView,我们可以简化WeeklyView-

struct CircleDayView: View {
    var day: Weekday
    var selected: Bool
    var selectedColor: Color
    var unselectedColor:Color = .indigo
    var body: some View {
        ZStack {
            Circle()
                .fill(selected ? selectedColor : unselectedColor)
                .frame(width: 49, height: 49)
                .opacity(0.4)
            
            Text(day.shortSymbol)
                .foregroundColor(Color.white)
                .fontWeight(.semibold)
                .padding(.vertical, 12)
        }
    }
}

struct CircleDayView_Previews: PreviewProvider {
    static var previews: some View {
        CircleDayView(day: .monday, selected: false, selectedColor: .red, unselectedColor: .green)
    }
}

struct WeeklyView: View {
    @ObservedObject var habit: HabitEntity
    var body: some View {
        HStack(spacing: 8) {
            ForEach(Weekday.orderedDays, id: \.self) { day in
                CircleDayView(day: day, selected: habit.weekdays.contains(day), selectedColor: habit.color)
                .onTapGesture {
                    withAnimation {
                        if habit.weekdays.contains(day) {
                            habit.weekdays.remove(day)
                        } else {
                            habit.weekdays.insert(day)
                        }
                    }
                }
            }
        }
    }
}

请注意CircleDayView是如何从HabitEntity解耦的

相关问题