我试图让斯威夫特协议,我可以使用UILabel,UITextField以及UITextView结合了他们text,attributedText和font性能。
然而,不幸的是,这三个类与它们是否为这些属性使用可选类型或隐式解包的可选类型不一致。
例如,如果我创建此协议:
protocol MyProtocol: class {
var font: UIFont? { get set }
}
Run Code Online (Sandbox Code Playgroud)
我应用它:
extension UILabel: MyProtocol { }
extension UITextField: MyProtocol { }
extension UITextView: MyProtocol { }
Run Code Online (Sandbox Code Playgroud)
它适用于UITextFieldandUITextView但是UILabel的font属性是UIFont!,所以编译器说不UILabel符合MyProtocol.
此外,textandattributedText是可选的 ( String?) for UILabelandUITextField但隐式解包 for UITextView( String!)。因此,对于所有三个属性,哪些使用可选项以及哪些使用隐式展开的可选项甚至不一致。
那么我不得不font在协议中重命名为例如。uiFont …
为了提供一些背景信息,我正在编写我们应用程序的订单跟踪部分,该部分会经常从服务器重新加载订单状态。屏幕上的 UI 是用 SwiftUI 开发的。我需要屏幕上有一个可选图像,该图像随着订单的进展而变化。
当我尝试以下操作时,一切正常......
我的 viewModel 是一个 ObservableObject:
internal class MyAccountOrderViewModel: ObservableObject {
这有一个已发布的属性:
@Published internal var graphicURL: URL = Bundle.main.url(forResource: "tracking_STAGEONE", withExtension: "gif")!
在 SwiftUI 中使用该属性如下:
GIFViewer(imageURL: $viewModel.graphicURL)
我的问题是该graphicURL属性的占位符值可能不正确,而我的要求是它是可选的。将已发布的属性更改为:@Published internal var graphicURL: URL?会导致我的 GIFViewer 出现问题,它不接受可选 URL:
Cannot convert value of type 'Binding<URL?>' to expected argument type 'Binding<URL>'
尝试明显展开 会graphicURL产生此错误:
Cannot force unwrap value of non-optional type 'Binding<URL?>'
使这项工作有效的正确方法是什么?我不想在属性中添加一个值,并检查该属性是否等于占位符值(即将其视为 nil),或者假设该属性始终为非 nil 并以某种方式不安全地强制解开它。
我一直在调查这个错误一段时间,但我仍在努力寻找答案。
我理解这个错误背后的概念,但我不明白为什么它仍然通知我,即使我觉得我已经从等式中删除了任何 nil 值(<-短语,而不是代码)。
struct NickName: View {
var name: String = ""
@AppStorage("current_user") var user = ""
var body: some View {
Text(String(name.first!)) //It notifies me here, i.e. 'Thread 1: Fatal error...'
.fontWeight(.heavy)
.foregroundColor(.white)
.frame(width: 50, height: 50)
.background((name == user ? Color.blue : Color.green).opacity(0.5))
.clipShape(Circle())
}}
Run Code Online (Sandbox Code Playgroud)
这个结构通过一系列视图传递,它应该在消息传递界面中呈现。
感谢您的帮助,我觉得好像我一直在以错误的方式看待这个问题,或者我可能遗漏了一些东西,这是一个简单的解决方法:)