You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DateComponentsFormatter处理DateComponents时遇3个错误求助

问题修复方案

错误原因解析

  1. 返回类型不匹配:remainderCompValue()声明返回DateComponents,但你写的是赋值语句(= [.year]),赋值操作返回()(Void),类型完全不兼容。
  2. 上下文缺失:直接写.year时编译器找不到对应的枚举类型,需明确关联Calendar.Component(或在正确上下文中简写)。
  3. API使用错误:DateComponents本身没有DateComponentsFormatter成员,DateComponentsFormatter是独立工具类,需单独实例化后传入DateComponents生成格式化字符串。

修正后的完整代码

import SwiftUI
import Foundation

struct ContentView: View {
    
    @State private var birthDay: Date = Calendar.current.date(byAdding: DateComponents(year: -30), to: Date()) ?? Date()
    
    // 用计算属性替代lazy var,确保birthDay变化时自动更新
    private var remainder: Date? {
        Calendar.current.date(byAdding: DateComponents(year: 73), to: birthDay)
    }
    
    private var remainderComp: DateComponents? {
        guard let remainder = remainder else { return nil }
        return Calendar.current.dateComponents([.year], from: Date(), to: remainder)
    }
    
    // 单独创建可复用的DateComponentsFormatter实例
    private lazy var componentsFormatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.year]
        formatter.unitsStyle = .full // 可选:控制显示样式,比如.short会显示"1年",.full显示完整格式
        return formatter
    }()

    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    Text("Your birthday...?")
                        .font(.title)
                    DatePicker("", selection: $birthDay, in: ...Date(), displayedComponents: .date)
                        .datePickerStyle(.compact)
                        .labelsHidden()
                    Text("""
                         The world's average life expectancy in 2022 is
                         73 years
                         """)
                    .multilineTextAlignment(.center)
                    Text("You still have: ")
                    // 直接显示格式化后的文本
                    Text(remainderCompValue())
                    Spacer()
                }
            }
        }
    }
    
    // 修改返回类型为String,返回格式化后的结果
    private func remainderCompValue() -> String {
        guard let comp = remainderComp, let formattedString = componentsFormatter.string(from: comp) else {
            return "0 years on earth"
        }
        return "\(formattedString) on earth"
    }
}

关键修改点说明

  • 替换lazy var为计算属性:remainder和remainderComp改为计算属性,确保用户修改birthDay时自动重新计算剩余年份,而非仅初始化一次。
  • 正确配置Formatter:在闭包中初始化DateComponentsFormatter并设置属性,保证复用性和代码整洁。
  • 调整函数返回类型:remainderCompValue()返回String类型,直接输出格式化后的文本,解决类型不匹配问题。
  • 安全解包处理:对可选类型做安全解包,避免运行时崩溃。

内容的提问来源于stack exchange,提问作者Walter Pak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:46:04