问题描述
最好用一些代码解释该问题。
步骤1
public struct Example<Content: View> {
let content: () -> Content
init(@viewbuilder content: @escaping () -> Content) {
self.content = content
}
func contentView() -> Content {
self.content()
}
}
步骤2
现在,当我添加一个内部结构时,编译器会抱怨不支持静态存储的属性。
public struct Example<Content: View> {
let content: () -> Content
init(@viewbuilder content: @escaping () -> Content) {
self.content = content
}
func contentView() -> Content {
self.content()
}
public struct ActionKey: Hashable,Equatable,RawRepresentable {
public static let cancelButtonClicked = ActionKey("cancelButtonClicked") // Static stored properties not supported in generic types
public static func == (lhs: ActionKey,rhs: ActionKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(_ rawValue: String) {
self.init(rawValue: rawValue)
}
}
}
步骤3
要消除错误,我们需要将其转换为计算变量。
public static var cancelButtonClicked: ActionKey { get { ActionKey("cancelButtonClicked") } }
问题
除了已经很烦人之外,它还会变得更糟。我们还需要为完全不依赖它的结构提供通用参数。
_ = Example.ActionKey(rawValue: "cancelButtonClicked") // Generic parameter 'Content' Could not be inferred
// Fix
_ = Example<AnyView>.ActionKey(rawValue: "cancelButtonClicked")
如果我们能以某种方式避免将泛型类型放在外部作用域中,则可以避免。但是,将类型存储在变量中不会让我使用它。所以我被困住了。有人有答案吗?
public struct Example<Content: View> {
let content: Any
let contentType: Any.Type
init<Content>(@viewbuilder content: @escaping () -> Content) {
self.content = content
self.contentType = Content.self
}
func contentView() -> ?? {
self.content() // ??
}
public struct ActionKey: Hashable,RawRepresentable {
public static var cancelButtonClicked: ActionKey { get { ActionKey("cancelButtonClicked") } }
public static func == (lhs: ActionKey,rhs: ActionKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(_ rawValue: String) {
self.init(rawValue: rawValue)
}
}
}
是将内部结构置于所有外部的唯一解决方案吗?
解决方法
这是可行的方法(但是我会把它放在外面,就像ButtonStyle
在Button
之外)……无论如何,这里是:
public struct Example {
private let content: AnyView
init<Content: View>(@ViewBuilder content: @escaping () -> Content) {
self.content = AnyView(content())
}
func contentView() -> some View {
self.content
}
public struct ActionKey: Hashable,Equatable,RawRepresentable {
public static let cancelButtonClicked = ActionKey("cancelButtonClicked") // Static stored properties not supported in generic types
public static func == (lhs: ActionKey,rhs: ActionKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(_ rawValue: String) {
self.init(rawValue: rawValue)
}
}
}