【问题标题】:.fullScreenCover always opening same Detail Page.fullScreenCover 始终打开相同的详细信息页面
【发布时间】:2021-02-08 17:19:40
【问题描述】:

所以我在这里遇到了一些问题,我希望很容易解决,只是目前无法解决。我正在通过一些CoreData信息(帖子)循环并返回图像网格,我希望能够单击这些图像并打开DetailView的fullScreenCover,其中包含正确的信息。使用当前代码,DetailView 始终显示第一篇文章中的数据。如果我将它从 Button 更改为 NavigationLink NavigationLink(destination: DetailView(post: post)),正如代码中注释的那样,它可以完美运行,但不会给我想要的 fullScreenCover 行为。我在这里做错了什么?提前致谢!

@FetchRequest(entity: Post.entity(), sortDescriptors: []) var posts: FetchedResults<Post>

enum ActiveSheet: Identifiable {
        case detail, addNew
        
        var id: Int {
            hashValue
        }
    }
@State var activeSheet: ActiveSheet?

var body: some View {

ForEach(posts.reversed(), id: \.self) { post in
    
    VStack {
    Button(action: { activeSheet = .detail }){
    //NavigationLink(destination: DetailView(post: post)){
    ZStack {
    Image(uiImage: UIImage(data: post.mainImage ?? self.image)!)
        VStack {
        Text("\(post.title)")
        Text("\(post.desc)")
        }
    }
}
.fullScreenCover(item: $activeSheet) { item in
            switch item {
            case .detail:
                DetailView(post: post)
            case .addNew:
                AddNewView()
            }
        }
}
}
}

【问题讨论】:

标签: ios swift swiftui


【解决方案1】:

我暂时将帖子数组设为静态而不是来自 Core Data 并模拟对象/结构以便我可以轻松测试,但主体应该保持不变:

struct ContentView : View {
    //@FetchRequest(entity: Post.entity(), sortDescriptors: []) var posts: FetchedResults<Post>
    var posts : [Post] = [Post(title: "1", desc: "desc1"),
                          Post(title: "2", desc: "desc2"),
                          Post(title: "3", desc: "desc3")]
    
    enum ActiveSheet: Identifiable {
        case detail(post: Post)
        case addNew
        
        var id: UUID {
            switch self {
            case .detail(let post):
                return post.id
            default:
                return UUID()
            }
        }
    }
    @State var activeSheet: ActiveSheet?
    
    var body: some View {
        
        ForEach(posts.reversed(), id: \.self) { post in
            
            VStack {
                Button(action: { activeSheet = .detail(post: post) }){
                    ZStack {
                        //Image(uiImage: UIImage(data: post.mainImage ?? self.image)!)
                        VStack {
                            Text("\(post.title)")
                            Text("\(post.desc)")
                        }
                    }
                }
            }
            .fullScreenCover(item: $activeSheet) { item in
                switch item {
                case .detail(let post):
                    DetailView(post: post)
                case .addNew:
                    AddNewView()
                }
            }
        }
    }
}

struct DetailView : View {
    var post: Post
    
    var body : some View {
        Text("Detail \(post.id)")
    }
}

struct AddNewView : View {
    var body : some View {
        Text("add")
    }
}

struct Post : Hashable {
    var id = UUID()
    var title : String
    var desc : String
}

基本思想是,与其在第一次渲染时创建fullScreenCover,不如根据activeSheet 创建它,以便动态创建它。您已经使用item:activeSheet 走在了正确的轨道上——问题是它与实际帖子无关,因为您只是使用按钮设置activeSheet = .detail

我已向case detail 添加了一个关联属性,可让您实际将帖子与其关联。然后,在fullScreenCover 中,您可以看到我在创建DetailView 时使用了该关联值。

您可能需要稍作调整以适应您的 Post 模型,但概念将保持不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    相关资源
    最近更新 更多