【发布时间】: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,并且它们都必须是唯一的;它不能是可选的。 -
感谢您的帮助,但我试过了,还是不行。我在上面添加了更多细节