如何获取文本以显示科普特日历日期 SwiftUI 如果让守卫强制展开你的问题

问题描述

我正在尝试使用 NSCalendar 初始值设定项,但我无法理解文档。到目前为止我所拥有的是

    struct SwiftUIView: View {
    var body: some View {
        
        
        let Date = NSCalendar.init(calendarIdentifier: .coptic)
        
        Text("\(Date)")
        
        
        
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

它给了我一个错误说 “可选类型‘NSCalendar’的值?必须解包为'NSCalendar'类型的值"

如果有人能帮我解决这个问题,那就太好了。谢谢

解决方法

你想要的 Swift 接口是 Calendar 而不是 NSCalendar:

let calendar = Calendar(calendarIdentifier: .coptic)

NSCalendar 接口来自 ObjC,如果日历的名称未知,则记录为返回 nil(您可以在 ObjC 中为该参数传递任意字符串)。

Swift Calendar 接口不会失败,因为它不允许您创建未知标识符。

有许多以“NS”开头的类型是从 Objective-C 桥接而来的。有一个去掉“NS”前缀的 Swift 版本是很常见的。当你看到这个时,你通常应该使用 Swift 版本。它通常会以更像 Swift 的方式运行。

如果您的目标是在科普特日历上显示当前日期,那么您将需要的不止这些。日历代表整个日历,而不是特定日期。您将需要 DateFormatter 才能创建本地化字符串。

例如:

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.calendar = Calendar(identifier: .coptic)
dateFormatter.eraSymbols = ["BC","AM"] // See below
print(dateFormatter.string(from: Date()))

// Baramouda 18,1737 AM

(我相信日历中存在一个错误,即科普特日历具有时代符号“ERA0”和“ERA1”。我相信此日历的正确符号是“BC”和“AM”。您可以通过将它们直接分配给日期格式化程序。如果我认为这是一个错误并且对您有影响,我建议您打开一个 Apple Feedback。另请参阅 DateFormatter 文档以了解如何自定义此字符串。)

对于 xTwisteDx 的观点,要将其放入 SwiftUI,您需要以下内容:

struct ContentView: View {

    let dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.eraSymbols = ["BC","AM"] // Workaround for Foundation bug
        dateFormatter.calendar = Calendar(identifier: .coptic)
        return dateFormatter
    }()

    func today() -> String {
        dateFormatter.string(from: Date())
    }

    var body: some View {
        Text(today())
            .padding()
    }
}
,

好的,这是 Optionals 的问题。每当您看到 ?! 时,您都可以假定它是可选的。本质上它是 Type? 的原因,请注意 ? 是因为它可能返回了 nil 值。例如,以下代码片段在 Swift 中是可能的

let forceUnwrappedString: String!
let optionalString: String?
let safeString: String = "Hello World!"

print(forceUnwrappedString) //This WILL crash,the variable is nil.
print(optionalString) //This MAY crash,if the value is nil.
print(safeString) //This WON'T crash.

处理这些问题的方法是使用 if letguard 语句进行检查。或者,您也可以在检查 nil 后强制展开。

如果让

在这个例子中,如果 optionalString 为 nil,打印语句将不会发生。但是,如果 optionalString 包含一个值,它会。它本质上是一种告诉编译器检查 nil 值并仅在安全的情况下运行代码的方法。

if let safeString = optionalString {
    print(safeString)
}

守卫

在这个例子中,它与 If Let 的工作原理相同,但一个显着的区别是 safeString 可以在比 If Let 更大的范围内访问,如果值没有“解包”,它也会返回所以如果它没有安全地解包,它下面的任何代码都不会被调用。

guard let safeString = optionalString { else return }
print(safeString)

强制展开

强制展开是您应该避免的,但也有可以接受的情况。这是强制展开的示例。请注意,我使用了 !,它基本上表示“我知道这个值不是 nil,请使用它”。这是您唯一应该使用它的时候,您可以保证没有 nil 值。

let someString: String? 

someString = "Hello World!"

print(someString!)

你的问题

在您的问题上下文中,NSCalendar.init(calendarIdentifier: .coptic) 返回一个可选类型,或者,someType? 意味着它可能是 nil 解决方案如下。

let Date = NSCalendar.init(calendarIdentifier: .coptic)
        
if let safeDate = Date {
        Text("\(safeDate)")
} else {
    //The date value was nil,do something else
}