“类型 '()' 无法符合 'View'”错误 Swift

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

我在

Type '()' cannot conform to 'View'"
线上收到
if let birthday = contact.birthday, let birthdayDate = Calendar.current.date(from: birthday) {
错误。查看错误日志后,我发现:
Only concrete types such as structs, enums and classes can conform to protocols
Required by static method 'buildBlock' where 'C0' = '()'

这是我的生日行文件,我遇到了

"Type '()' cannot conform to 'View'"
错误

//
//  BirthdayRow.swift
//  B-Day
//
//  Created by Joshua Wolfson on 29/7/2023.
//

import SwiftUI

struct GaugeProgressStyle: ProgressViewStyle {
    var strokeColor = Color.primary
    var strokeWidth = 7.0
    
    func makeBody(configuration: Configuration) -> some View {
        let fractionCompleted = configuration.fractionCompleted ?? 0
        
        return ZStack {
            
            Circle()
                .stroke(.tertiary, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round))
            
            Circle()
                .trim(from: 0, to: fractionCompleted)
                .stroke(strokeColor, style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round))
                .rotationEffect(.degrees(-90))
        }
    }
}


struct BirthdayRow: View {
    @State private var progress: Double
    
    let contact: Contact
    
    init(contact: Contact) {
        self.contact = contact
        
        self.progress = Self.calculateProgress(contact: contact)
    }
    
    static func calculateProgress(contact: Contact) -> Double {
        guard let birthday = contact.birthday, let birthdayDate = Calendar.current.date(from: birthday) else {
            return 0.0
        }
        
        let currentDate = Date()
        let calendar = Calendar.current
        
        let daysInYear: Double = 365.0
        let daysRemaining = Double(calendar.dateComponents([.day], from: currentDate, to: birthdayDate).day ?? 0)
        return (daysInYear - daysRemaining) / daysInYear * 100.0
    }
    
    var body: some View {
        VStack {
            HStack {
                VStack(alignment: .leading) {
                    Text("\(contact.firstName) \(contact.lastName)")
                        .font(.title3)
                        .fontWeight(.bold)
                    
                    HStack {
                        Text(contact.category)
                            .foregroundColor(Color.gray)
                        
                        Text("•")
                            .fontWeight(.black)
                        
                        if let birthday = contact.birthday, let birthdayDate = Calendar.current.date(from: birthday)
                        { //I'm receiving "Type '()' cannot conform to 'View'" error here
                            let dateFormatter = DateFormatter()
                            dateFormatter.dateFormat = "dd/MM/yyyy"
                            Text(dateFormatter.string(from: birthdayDate))
                                .foregroundColor(Color.gray)
                        } else {
                            Text("Unknown")
                                .foregroundColor(Color.red)
                        }
                    }
                }
                
                Spacer()
                
                ProgressView(value: progress, total: 100.0)
                    .progressViewStyle(GaugeProgressStyle())
                    .frame(width: 26, height: 26)
                    .contentShape(Rectangle())
            }
            .padding(.horizontal)
        }
    }
}




struct BirthdayRow_Previews: PreviewProvider {
    static var contacts = ModelData().contacts
    static var previews: some View {
        Group {
            BirthdayRow(contact: contacts[0])
            BirthdayRow(contact: contacts[1])
        }
        .previewLayout(.fixed(width: 300, height: 70))
    }
}

这是我的 ModelData 文件,有帮助吗?

//
//  ModelData.swift
//  B-Day
//
//  Created by Joshua Wolfson on 5/8/2023.
//

import Foundation
import Contacts
import SwiftUI


final class ModelData: ObservableObject {
    @Published var contacts: [Contact] = []
    
    init() {
        Task {
            let fetchedContacts = await fetchAllContacts()
            DispatchQueue.main.async {
                self.contacts = fetchedContacts
            }
        }
    }
}

struct Contact: Identifiable {
    let id = UUID()
    let category: String // This will contain the group name
    let firstName: String
    let lastName: String
    let birthday: DateComponents?
}


func fetchAllContacts() async -> [Contact] {
    var contacts = [Contact]()
    let store = CNContactStore()
    
    // Request the contact's identifier and group information
    let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactIdentifierKey, CNGroupNameKey, CNGroupIdentifierKey] as [CNKeyDescriptor]
    
    let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
    fetchRequest.unifyResults = true // To fetch contacts from all accounts and groups
    
    do {
        try store.enumerateContacts(with: fetchRequest) { contact, _ in
            // Fetch the group name using the identifier
            if let groupName = try? store.groups(matching: nil).first(where: { group in
                return group.identifier == contact.identifier
            })?.name {
                contacts.append(Contact(category: groupName, firstName: contact.givenName, lastName: contact.familyName, birthday: contact.birthday))
            } else {
                contacts.append(Contact(category: "Ungrouped", firstName: contact.givenName, lastName: contact.familyName, birthday: contact.birthday))
            }
        }
    } catch {
        print("Error: \(error.localizedDescription)")
    }
    
    return contacts
}

我的内容视图如下:

//
//  ContentView.swift
//  B-Day
//
//  Created by Joshua Wolfson on 28/7/2023.
//

import Contacts
import SwiftUI

struct ContentView: View {
    @State private var selection = "All"
    @EnvironmentObject var modelData: ModelData
    var filteredContacts: [Contact] {
        modelData.contacts.filter { contact in
            (selection == "All" || contact.category == selection)
        }
    }
    var availableCategories: [String] {
        var categories = ["All"]
        categories.append(contentsOf: Set(modelData.contacts.map { $0.category }).sorted())
        return categories
    }
    var body: some View {
        
        NavigationStack{
            List {
                ForEach(filteredContacts) {contact in
                    NavigationLink {
                        BirthdayDetail(contact: contact)
                    } label: {
                        BirthdayRow(contact: contact)
                    }
                }
            }
            
            
            .navigationTitle(selection == "All" ? "Birthdays" : selection)
            
            .toolbar {
                
                ToolbarItem (placement: .navigationBarLeading){
                    Menu(content: {
                        Picker("Destination", selection: $selection) {
                            ForEach(availableCategories, id: \.self) {
                                Text($0)
                            }
                        }
                    },
                         label: { Label ("Filter", systemImage: "line.horizontal.3.decrease.circle") })
                }
                
                ToolbarItem (placement: .navigationBarTrailing) {
                    Button {
                        print("Sync Contacts")
                    } label: {
                        Image (systemName: "arrow.triangle.2.circlepath")
                    }
                }
                
                ToolbarItem (placement: .navigationBarTrailing) {
                    Button {
                        print("Add Birthday")
                    } label: {
                        Image(systemName: "plus")
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

这是我的主要内容:

//  B_DayApp.swift
//  B-Day
//
//  Created by Joshua Wolfson on 28/7/2023.
//

import SwiftUI
import Contacts

@main
struct B_DayApp: App {
    @StateObject private var modelData = ModelData()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(modelData)
                .onAppear {
                    Task.init {
                        await fetchAllContacts()
                    }
                }
        }
    }
}

p.s 抱歉代码超载,这是我的第一篇文章。

swift if-statement swiftui contacts swiftui-foreach
1个回答
0
投票

您不能将以下代码放入 if 语句中。

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

上面的代码无法执行,因为它在

var body: some View
里面。

因此,您应该避免在

var body: some View
内处理上述代码。

© www.soinside.com 2019 - 2024. All rights reserved.