SwiftUI 和 Core Data:在视图中使用实例成员作为参数的 fetch 请求

如何解决SwiftUI 和 Core Data:在视图中使用实例成员作为参数的 fetch 请求

我似乎陷入了第 22 条军规的境地。也许我的方法在这里完全错误。我希望有人能帮帮忙。我想使用访问特定现实世界地标的用户的反馈来创建基于星级的评级显示。 在 CoreData 中,我有一个名为 rating 的实体,具有名为 rating (Int32) 和地标 (String) 的属性。我想获得与给定地标相关的所有评分的平均值,以便在视图中为每个评分显示星星。 这是视图的代码

struct TitleImageView: View {
    @Environment(\.managedobjectContext) var viewContext : NSManagedobjectContext
    let landmark: Landmark 
    var body: some View {
        
        Image(landmark.imageName)
            .resizable()
            .shadow(radius: 10 )
            .border(Color.white)
            .scaledToFit()
            .padding([.leading,.trailing],40)
            .layoutPriority(1)
            .overlay(TextOverlay(landmark: landmark))
            .overlay(ratingsOverlay(rating: stars))
    }
}

这是提取(当提取的参数是硬编码时,它按预期工作):

let fetchRequest = rating.fetchRequestForLandmark(landmark: landmark.name)
    var ratings: FetchedResults<rating> {
            fetchRequest.wrappedValue
    }
        var sum: Int32 {
            ratings.map { $0.rating }.reduce(0,+)
        }
        var stars : Int32 {
            sum / Int32(ratings.count)
        } 

问题是这样的:当我在视图主体之前插入 fetch 时,我收到警告

“不能在属性初始化器中使用实例成员‘landmark’;属性初始化器在‘self’可用之前运行”

当我把 fetch 放在 body 之后,我得到:

“包含声明的闭包不能与函数构建器‘viewbuilder’一起使用”(参考 var 评级)

是否有解决这个难题的简单方法,还是我必须回到众所周知的绘​​图板?谢谢。

解决方法

如何将 fetch 包装在一个计算属性中,该属性返回一个 sum 和 stars 元组?形状略有不同,结果相同。计算出来的属性可以引用其他属性,这样就扫除了 swift-init 的障碍!

var metrics : (sum: Int,stars: Int) {
let fetchRequest = Rating.fetchRequestForLandmark(landmark: landmark.name)
var ratings: FetchedResults<Rating> {
    fetchRequest.wrappedValue
}

let sum = ratings.map { $0.rating }.reduce(0,+)
let stars = sum / ratings.count

return (sum: sum,stars: stars)

}

,

感谢提供建议的人。经过长时间的中断,我回到了这个问题并得出了这个解决方案(基于 HackingWithSwift 教程:https://www.hackingwithswift.com/books/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui) 代码如下:

struct RatingsView: View {
    var fetchRequest: FetchRequest<Rating>
    
    var body: some View {

        HStack(spacing: 0.4){
            ForEach(1...5) { number in
                if number > stars {
                    //Image(systemName: "star")
                } else {
                    Image(systemName: "star.fill")
                }
            }
        }
    }
    
    init(filter: String) {
        fetchRequest = FetchRequest<Rating>(entity: Rating.entity(),sortDescriptors: [],predicate: NSPredicate(format: "%K == %@","landmark",filter))
    }
    var sum: Int16 {
        fetchRequest.wrappedValue.reduce(0) { $0 + $1.rating }
        }
    
    var stars : Int {
        var starCount:Int
        if fetchRequest.wrappedValue.count > 0 {
            starCount = Int(sum) / fetchRequest.wrappedValue.count
        } else {
            starCount = 0
        }
        return starCount
    }
}

我不确定这是否是绝对的最佳解决方案,但它按预期工作。 希望这可以帮助其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?