Ric*_*hiy 6 initializer ios swift swiftui viewbuilder
代码:
import SwiftUI
public struct Snackbar<Content>: View where Content: View {
private var content: Content
// Works OK
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
init(_ text: String) {
self.init {
Text(text) // cannot convert value of type 'Text' to closure result type 'Content'
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading)
}
}
public var body: some View {
HStack {
VStack(alignment: .leading, spacing: 4) {
content
}
Spacer()
}
.frame(maxWidth: .infinity,
minHeight: 26)
.padding(.fullPadding)
.background(Color.black)
.clipShape(RoundedRectangle(cornerRadius: .defaultCornerRadius))
.shadow(color: Color.black.opacity(0.125), radius: 4, y: 4)
.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
无法将“Text”类型的值转换为闭包结果类型“Content”
我试图实现的目标是拥有 2 个独立的初始值设定项,一个用于类型的内容View
,另一个是字符串的快捷方式,它将放置一个Text
具有某种样式的预定义组件来代替Content
.
为什么我会收到此错误,如果Text
是some View
并且我认为它应该编译。
小智 6
对此的通用解决方案是提供一个在语义上等价于 的包装器some View
。AnyView
是内置的并服务于此目的。
init(_ text: String) where Content == AnyView {
self.init {
AnyView(
Text(text)
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading)
)
}
}
Run Code Online (Sandbox Code Playgroud)
另外,将您的代码更改为
private let content: () -> Content
public init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
Run Code Online (Sandbox Code Playgroud)
这样您就不必将结果包装content
在另一个闭包中。
VStack(alignment: .leading, spacing: 4, content: content)
Run Code Online (Sandbox Code Playgroud)
您可以指定 的类型Content
。
代码:
public struct Snackbar<Content>: View where Content: View {
private var content: Content
// Works OK
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
init(_ text: String) where Content == ModifiedContent<Text, _EnvironmentKeyWritingModifier<TextAlignment>> {
self.init {
Text(text)
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading) as! ModifiedContent<Text, _EnvironmentKeyWritingModifier<TextAlignment>>
}
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
这里唯一的区别是和强制where
转换init
为 内的类型init
。
为了避免特定类型,您可以将其抽象为单独的视图:
init(_ text: String) where Content == ModifiedText {
self.init {
ModifiedText(text: text)
}
}
/* ... */
struct ModifiedText: View {
let text: String
var body: some View {
Text(text)
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5406 次 |
最近记录: |