我的目标是制作一个可重用的视图协议,它继承 SwiftUI View 协议并提供一些默认功能,用于根据视图内容的状态加载显示不同的视图。
这样,我不必为我创建的每个视图重写相同的代码,并使代码更清晰。
我制作了一个“DelayedContentView”协议,它根据视图内容是否已加载来显示两个不同的视图主体。当我尝试实施它时,问题就出现了。“loadedBody”和“unloadedBody”属性不能是“some View”类型,即使它们与 SwiftUI View 的 Body AssociatedType 类型相同。
我的应用程序中有各种远程获取数据的视图。每个视图显示两个视图主体:一个用于获取内容时的视图主体,另一个用于获取完成时的视图主体。
public protocol View {
associatedtype Body : View
var body: Self.Body { get }
}
Run Code Online (Sandbox Code Playgroud)
protocol DelayedContentView:View {
func contentLoaded() -> Bool
var loadedBody: Self.Body { get }
var unloadedBody: Self.Body { get }
}
extension DelayedContentView {
//Default implementation that I won't have to rewrite for each view.
var body: some View {
if contentLoaded() {
return self.loadedBody
}else{
return self.unloadedBody
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct ExampleView:DelayedContentView {
func contentLoaded() -> Bool {
//Ask viewModel if content is loaded.
return false
}
var loadedBody: some View {
Text("Content is loaded.")
}
var unloadedBody: some View {
Text("Fetching content...")
}
}
Run Code Online (Sandbox Code Playgroud)
Compile Error: Type 'ExampleView' does not conform to protocol 'DelayedContentView'
Run Code Online (Sandbox Code Playgroud)
我认为协议继承是处理这种情况的正确工具,但也许我错了?
该协议DelayedContentView必须添加另外两种关联类型来表示两种附加视图类型:一种用于“已加载”视图,另一种用于“已卸载”视图。不可能,Self.Body因为它显然会被违反,因为你需要身体中有条件的视图。
protocol DelayedContentView: View {
associatedtype LoadedBody: View
associatedtype UnloadedBody: View
func contentLoaded() -> Bool
var loadedBody: LoadedBody { get }
var unloadedBody: UnloadedBody { get }
}
Run Code Online (Sandbox Code Playgroud)
现在您已经有了其中两个泛型类型,这Self.Body将是这两个类型的复合类型:
extension DelayedContentView {
@ViewBuilder // needed to create a _ConditionalContent type from if/else
var body: some View {
if contentLoaded() {
self.loadedBody
} else {
self.unloadedBody
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的特定视图将声明什么LoadedView和UnloadedView类型。例如,在您的 中ExampleView,它们都将是Text,并且Body将是_ConditionalContent<Text,Text>。
| 归档时间: |
|
| 查看次数: |
4630 次 |
| 最近记录: |