【问题标题】:Unable to infer complex closure return type; add explicit type to disambiguate Swift UI无法推断复杂的闭包返回类型;添加显式类型以消除 Swift UI 的歧义
【发布时间】:2020-07-31 20:10:26
【问题描述】:

当我将 foreach 循环保留在视图中时,我收到一条错误消息,提示视图“无法推断复杂的闭包返回类型;添加显式类型以消除歧义”。当我将我的 foreach 循环移出视图时,它工作正常。我刚开始在执行循环对象之前遇到此错误,然后才循环直到将“虚拟字符串”传递到ExerciseTableRow视图中的某个数字。不知道如何解决这个问题。提前谢谢!

struct PassedExerciseCard: View {
    var exercise : String
    var sets : [ExerciseSet]
    
    var body: some View {
        
        VStack{
            Text(exercise).font(.title).padding(.bottom, 5)
            Group{
                HStack{
                    Group{
                        Text("Set")
                        Text("Weight")
                        Text("Reps")
                    }.padding(.horizontal, 30)
                    .offset(x: -15, y: -5)
                    
                }
                VStack{
                    ForEach(sets, id: \.self){ (set : ExerciseSet) in
                        ExerciseTableRow(set: set.set, readOnly: true, setWeight: set.weight, setReps: set.reps)
                    }
                }.padding(.bottom, 5)
            }.offset(x: 20, y: 0)
            
            
        }
        .padding()
        .background(Color.offWhite)
        .cornerRadius(20)
        .shadow(color: Color.black.opacity(0.2), radius: 10, x:10, y:10)
        .shadow(color: Color.white.opacity(0.7), radius: 10, x:-5, y:-5)
        .padding(.vertical)
    }
}

struct PassedExerciseCard_Previews: PreviewProvider {
    
    static var exercise :[ExerciseSet] = []
    
    static var previews: some View {
        PassedExerciseCard(exercise: "Bench", sets: exercise)
    }
}

更新

我了解到我遇到的错误根本不是错误。实际的错误是编译器认为我没有作为 NSManagedObject 的练习集的属性。我更新了对象以产生想法,并更新了 foreach 循环以使用每个元素的特定 ID 作为标识符,但仍然没有运气。

更新代码:

struct PassedExerciseCard: View {
    var exercise : String
    var sets : [ExerciseSet]
    
    var body: some View {
        
        VStack{
            Text(exercise).font(.title).padding(.bottom, 5)
            Group{
                HStack{
                    Group{
                        Text("Set")
                        Text("Weight")
                        Text("Reps")
                    }.padding(.horizontal, 30)
                    .offset(x: -15, y: -5)
                    
                }
                VStack{
                    ForEach(sets, id: \.exerciseSetId){ set in
                        ExerciseTableRow(set: set.set, readOnly: true, setWeight: set.weight, setReps: set.reps)
                    }
                }.padding(.bottom, 5)
            }.offset(x: 20, y: 0)
            
            
        }
        .padding()
        .background(Color.offWhite)
        .cornerRadius(20)
        .shadow(color: Color.black.opacity(0.2), radius: 10, x:10, y:10)
        .shadow(color: Color.white.opacity(0.7), radius: 10, x:-5, y:-5)
        .padding(.vertical)
    }
}

NSManagedObject 实体:

import Foundation
import CoreData


extension ExerciseSet {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<ExerciseSet> {
        return NSFetchRequest<ExerciseSet>(entityName: "ExerciseSet")
    }

    @NSManaged public var reps: Int16
    @NSManaged public var set: Int16
    @NSManaged public var weight: Int16
    @NSManaged public var exerciseSetId: UUID?
    @NSManaged public var origin: Exercise?

}

此外,运动集与锻炼具有一对一的关系,即:

extension Workout {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Workout> {
        return NSFetchRequest<Workout>(entityName: "Workout")
    }

    @NSManaged public var date: String?
    @NSManaged public var muscle: String?
    @NSManaged public var workoutId: UUID?
    @NSManaged public var exercise: NSSet?
    
    public var wrappedDate: String{
        date ?? "Unknown Date"
    }
    
    public var wrappedMuscle: String {
        muscle ?? "Unknown Muscle"
    }
    
    public var exerciseArray: [Exercise] {
        let set = exercise as? Set<Exercise> ?? []
        
        return set.sorted{
            $0.wrappedName < $1.wrappedName
        }
     }

}

// MARK: Generated accessors for exercise
extension Workout {

    @objc(addExerciseObject:)
    @NSManaged public func addToExercise(_ value: Exercise)

    @objc(removeExerciseObject:)
    @NSManaged public func removeFromExercise(_ value: Exercise)

    @objc(addExercise:)
    @NSManaged public func addToExercise(_ values: NSSet)

    @objc(removeExercise:)
    @NSManaged public func removeFromExercise(_ values: NSSet)

}

在调用 PassedExerciseCard(抛出错误的地方)的视图中,我将 WorkoutEntity 上的属性:“exerciseArray”传递到我在 foreach 循环中使用的 sets 属性中。我相信这是发生错误的地方

练习表行:

struct ExerciseTableRow: View {
    @State public var weight : String = "0"
    @State public var reps : String = "0"
    var set : Int
    var readOnly : Bool
    var setWeight : Int
    var setReps : Int
    var body: some View {
        
        HStack{
            Text(String(set))
                .padding(.trailing, 40)
                .padding(.leading, 10)
            if readOnly == false{
                Group{
                    TextField("0", text: $weight)
                    TextField("0", text: $reps)
                }.textFieldStyle(RoundedBorderTextFieldStyle())
                    .frame(width: 50)
                    .multilineTextAlignment(.center)
                    .keyboardType(.numberPad)
                    .padding(.horizontal, 30)
            }
            else{
                Group{
                    Text(String(setWeight))
                    Text(String(setReps))
                }
                .frame(width: 50)
                    .overlay(
                        RoundedRectangle(cornerRadius: 5)
                            .stroke(Color.black, lineWidth: 1)
                    )
                    .padding(.bottom, 5)
                    .padding(.horizontal, 30)
            }
            
        }
        
        
    }
}

【问题讨论】:

  • 什么是ExceriseSet?为什么你认为\.self 是这里的有效 id?是否有正确类型的 ExceriseSet.set 可以传递给 ExerciseTableRow?化简,化简,化简,找出导致错误的最小块。那么问题一般会自己暴露出来吗?
  • 导致错误的代码块是 ForEach 循环。 ExerciseSet 是一个 NSManagedObject ,当我将 foreach 循环设置为: ForEach(sets, id: \.self){set in ExerciseTableRow(set: set.set, readOnly: true, setWeight: set.weight, setReps: set.代表)}
  • 它抛出一个错误“'NSManagedObject'类型的值没有成员'reps'”但是当我像在上面的代码中那样设置foreach循环时,它会抛出标题中所述的其他异常
  • exerciseSetId 是可选的。 Optional 不是 ID 类型。如果你想遍历一个列表,你需要确保每个元素都有一个 ID,并且它们都必须是唯一的;它不能是可选的。
  • 感谢您的帮助,但我试过了,还是不行。我在上面添加了更多细节

标签: swift swiftui


【解决方案1】:

发生错误是因为您的数据类型不匹配:

extension ExerciseSet {
    ...
    @NSManaged public var reps: Int16
    @NSManaged public var set: Int16
    @NSManaged public var weight: Int16
    ...
}

但在ExerciseTableRow 中,它们的类型为Int

var set : Int
var setWeight : Int
var setReps : Int

将它们更改为Int16 即可:

var set : Int16
var setWeight : Int16
var setReps : Int16

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多