4

我有一个带有自定义月份选择器的简单视图。每次您单击 V 形左或右时,

在 DateView 我有两个私有变量:startDateOfMonth2: DateendDateOfMonth2: Date。但它们仅在 DateView 中可用。

问题

如何使这两个变量在其他视图中可用?

我尝试将它们添加为 @Published 变量,但出现错误:

属性包装器不能应用于计算属性

我只发现了几个类似的问题,但我无法在我的代码中使用它们的答案。

import SwiftUI

class SelectedDate: ObservableObject {
    @Published var selectedMonth: Date = Date()
    
    @Published var startDateOfMonth2: Date {
        let components = Calendar.current.dateComponents([.year, .month], from: selectedMonth)
        let startOfMonth = Calendar.current.date(from: components)!
        return startOfMonth
    }

    @Published var endDateOfMonth2: Date {
        var components = Calendar.current.dateComponents([.year, .month], from: selectedMonth)
        components.month = (components.month ?? 0) + 1
        let endOfMonth = Calendar.current.date(from: components)!
        return endOfMonth
    }
}

struct DateView: View {
    @EnvironmentObject var selectedDate: SelectedDate
    
    static let dateFormat: DateFormatter = {
        let formatter = DateFormatter()
        formatter.setLocalizedDateFormatFromTemplate("yyyy MMMM")
        return formatter
    }()
    
    var body: some View {
        
        HStack {
            
            Image(systemName: "chevron.left")
                .frame(width: 50, height: 50)
                .contentShape(Rectangle())
                .onTapGesture {
                    self.changeMonthBy(-1)
            }
            
            Spacer()

            Text("\(selectedDate.selectedMonth, formatter: Self.dateFormat)")
            
            Spacer()
            
            Image(systemName: "chevron.right")
                .frame(width: 50, height: 50)
                .contentShape(Rectangle())
                .onTapGesture {
                    self.changeMonthBy(1)
            }
            
        }
        .padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
        .background(Color.yellow)
    }
    
    func changeMonthBy(_ months: Int) {
        if let selectedMonth = Calendar.current.date(byAdding: .month, value: months, to: selectedDate.selectedMonth) {
            self.selectedDate.selectedMonth = selectedMonth
        }
    }
}
4

2 回答 2

5

无需将您的计算值声明为已发布,因为它们取决于已发布的值。当发布的值发生变化时,它们会被重新计算。

class SelectedDate: ObservableObject {
    @Published var selectedMonth: Date = Date()
    
    var startDateOfMonth2: Date {
        let components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
        let startOfMonth = Calendar.current.date(from: components)!
        
        print(startOfMonth)
        return startOfMonth
    }

    var endDateOfMonth2: Date {
        var components = Calendar.current.dateComponents([.year, .month], from: self.selectedMonth)
        components.month = (components.month ?? 0) + 1
        let endOfMonth = Calendar.current.date(from: components)!

        print(endOfMonth)
        return endOfMonth
    }
}

当您endDateOfMonth2点击打印时,您会看到它正在发生变化。

于 2020-07-05T12:56:41.853 回答
-3

计算属性本质上是函数。它不能存储值,它只是从getter中的其他变量或属性计算值并将值更新回它在setter中计算的东西。仔细考虑你的属性的性质。大多数情况下,你可以直接读写计算属性。只记得是功能核心和属性皮肤

于 2020-07-05T13:09:27.217 回答