结构'ViewBuilder'要求'EmptyTableRowContent<V>确认视图:

问题描述 投票:0回答:1

上述错误发生在我正在创建的选择器处。我正在尝试从 @Bindable 类属性设置默认值。

在 Xcode 中扩展错误并没有真正帮助我

Requirement from conditional conformance of 'Section<TableHeaderRowContent<V, Text>, Content, EmptyTableRowContent<V>>' to 'View' (SwiftUI.Section)

所以我的选取器在完整视图的上下文中定义如下。请注意,父视图的调用站点很简单 - EditGreetingCardView(greetingCard: Bindable(greetingCard!))。

struct EditGreetingCardView: View {
    @Environment(\.modelContext) var modelContext

    @Query(sort: [
        SortDescriptor(\EventType.eventName)
         ]) var events: [EventType]
    
    @Bindable private var greetingCard: GreetingCard
    
    init(greetingCard: Bindable<GreetingCard>) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.largeTitleTextAttributes = [
            .foregroundColor: UIColor.systemGreen,
            .font: UIFont(name: "ArialRoundedMTBold", size: 35)!]
        navBarAppearance.titleTextAttributes = [
            .foregroundColor: UIColor.systemGreen,
            .font: UIFont(name: "ArialRoundedMTBold", size: 20)!]
        UINavigationBar.appearance().standardAppearance = navBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
        UINavigationBar.appearance().compactAppearance = navBarAppearance
        
        _greetingCard = greetingCard
    }
    
    var body: some View {
        NavigationView {
            Form {
                Section("Details") {
                    Picker("Select type", selection: $greetingCard.eventType) {
                        Text("Unknown Event")
                            .tag(Optional<EventType>.none) //basically added empty tag and it solve the case
                        
                        if events.isEmpty == false {
                            Divider()
                            
                            ForEach(events) { event in
                                Text(event.eventName)
                                    .tag(Optional(event))
                            }
                        }
                    }
                    
            .navigationTitle(greetingCard.cardName ?? "Card Not Named")
        }
    }
}

错误出现在选取器线上。我的 Bindable 定义为

@Bindable private var greetingCard: GreetingCard
班级是:

import Foundation
import SwiftData
import UIKit

/// This is used to build a gallery of Greeting Cards

@Model
final class GreetingCard: CustomDebugStringConvertible {
    var cardName: String?
    @Attribute(.externalStorage) var cardFront: Data?
    var eventType: EventType?
    var cardManufacturer: String?
    var cardURL: URL?
    @Relationship(deleteRule: .cascade, inverse: \Card.cardFront) var cards: [Card]? = []
    
    init(cardName: String?, cardFront: Data?, eventType: EventType? = nil, cardManufacturer: String? = nil, cardURL: URL?) {
        self.cardName = cardName
        self.cardFront = cardFront ?? UIImage(named: "frontImage")!.pngData()!
        self.eventType = eventType
        self.cardManufacturer = cardManufacturer
        self.cardURL = cardURL
    }
    
    /// A helper value that exposes the card as an Image either a blank image or the value of the image from the realted GreetingCard
    func cardUIImage() -> UIImage {
        let defaultImage: UIImage = UIImage(data: (cardFront)!) ?? UIImage(named: "frontImage")!
        return defaultImage
    }
}
swiftui
1个回答
0
投票

好吧,问题不是视图本身,而是由 SwiftData、CoreDataOptions 和 TextField 中的 Binding 引起的许多不同问题。以下博客文章确实帮助我理解和解决了我的代码:CoreData 和 Bindings

因此我重组了 SwiftData 类,为所有属性设置默认值,从而删除了可选值。现在,视图可以使用以下代码正常工作:

struct EditGreetingCardView: View {
    @Environment(\.modelContext) var modelContext
    @Bindable private var greetingCard: GreetingCard
    @State var frontImageSelected: Image? = Image("frontImage")
    @State var shouldPresentCamera = false
    @State var frontPhoto = false
    @State var captureFrontImage = false
    
    @Query(sort: [
        SortDescriptor(\EventType.eventName)
    ]) var events: [EventType]
    
    init(greetingCard: Bindable<GreetingCard>) {
        _greetingCard = greetingCard
    }
    
    var body: some View {
        Form {
            //        VStack {
            Section {
                Picker("Select type", selection: $greetingCard.eventType) {
                    Text("Unknown Event")
                        .tag(Optional<EventType>.none) //basically added empty tag and it solve the case
                    
                    if events.isEmpty == false {
                        Divider()
                        
                        ForEach(events) { event in
                            Text(event.eventName)
                                .tag(Optional(event))
                        }
                    }
                }
            }
            
            Section("Details") {
                TextField("Description", text: $greetingCard.cardName)
                TextField("Manufacturer", text: $greetingCard.cardManufacturer)
                TextField("Website", text: $greetingCard.cardURL)
            }
            
            Section("Card Image") {
                ZStack {
                    Image(uiImage: greetingCard.cardUIImage())
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .shadow(radius: 10 )
                    Image(systemName: "camera.fill")
                        .foregroundColor(.white)
                        .font(.largeTitle)
                        .shadow(radius: 10)
                        .frame(width: 200)
                        .onTapGesture { self.frontPhoto = true }
                        .actionSheet(isPresented: $frontPhoto) { () -> ActionSheet in
                            ActionSheet(
                                title: Text("Choose mode"),
                                message: Text("Select one."),
                                buttons: [ActionSheet.Button.default(Text("Camera"), action: {
                                    self.captureFrontImage.toggle()
                                    self.shouldPresentCamera = true
                                }),
                                          ActionSheet.Button.default(Text("Photo Library"), action: {
                                              self.captureFrontImage.toggle()
                                              self.shouldPresentCamera = false
                                          }),
                                          ActionSheet.Button.cancel()])
                        }
                        .sheet(isPresented: $captureFrontImage) {
                            ImagePicker(
                                sourceType: self.shouldPresentCamera ? .camera : .photoLibrary,
                                image: $frontImageSelected,
                                isPresented: self.$captureFrontImage)
                        }
                }
                .frame(width: 230, height: 230)
            }
        }
        .navigationTitle(greetingCard.cardName)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.