目标:
使用单个结构来管理自定义View
的外观和行为。
状态: 我有一个简单的 View 模型,它维护表示 View 的数据数组。在运行时,我按如下方式绘制这些 View :
struct MyView: View {
@ObservedObject var viewModel = MyViewModel()
var body: some View {
Vstack() {
ForEach(viewModel.data, id: \.id) { data in
switch data.shape {
case .circle:
MyViewCircle(isHighlighted: data.willHighlight)
case .ellipses:
MyViewEllipses(isHighlighted: data.willHighlight)
}
}
}
}
}
struct MyViewCircle: View {
var isHighlighted: Bool
var body: some View {
Circle()
/// a bunch of modifiers
}
}
struct MyViewEllipses: View {
var isHighlighted: Bool
var body: some View {
Ellipses()
///A bunch of modifiers that mirror exactly MyViewCircle
}
}
这工作正常,我可以更新我的 viewModel,这将相应地更新我的 View 。
但是,就我而言,MyViewCircle
或 MyViewEllipses
将具有完全相同的外观和行为,唯一不同的是它的形状,我还计划添加一个许多其他形状,甚至自定义绘制的形状。
我想做什么
我希望能够在 ForEach 循环中传递 enum
或 protocol
或其他内容,以绘制我想要的形状并进行简化,而不需要很长的 switch 语句。像这样的事情:
struct MyView: View {
@ObservedObject var viewModel = MyViewModel()
var body: some View {
VStack() {
ForEach(viewModel.data, id: \.id) { data in
MyViewProtocol(shape: data.shape, isHighlighted: data.IsHighlighted)
}
}
}
}
还有父类、父类(super class)、协议(protocol),无论 MyViewProtocol
的正确名称是什么,都类似于:
struct MyViewProtocol: View {
var shape: ShapeEnum
var isHighlighted: Bool
var body: some View {
switch shape:
case .circle:
Circle()
case .ellipses:
Ellipses()
case .triangle:
MyTrinagle()
// etc.....
}
}
我一直在搜索任何/所有 WWDC 演讲、YouTube 教程、媒体文章,我能找到的最接近的内容就在这里:Creating BaseView class in SwiftUI这对于创建一组 View 修饰符很有用,但是如果我希望能够使用由一个父结构 View 管理的大量形状,我仍然陷入困境。
我也可能遇到问题,因为对于像 SwiftUI 这样的声明性语言来说,这可能是一个危险的错误设计模式!
如果有任何提示或想法,我将非常感激!
最佳答案
我认为您无法避免使用 switch 语句,因为您需要 ShapeEnum
案例和实际 View 之间的映射,但您可以将其集中在一个地方:
enum ShapeEnum {
case circle, ellipse, square // etc...
}
extension ShapeEnum: View {
var body: AnyView {
switch self {
case circle: return AnyView(Circle())
case ellipse: return AnyView(Ellipse())
// ...
default: return AnyView(EmptyView())
}
}
}
用法可能是:
@State var shapes: [ShapeEnum] = [.circle, .circle, .ellipse]
var body: some View {
ForEach(shapes, id: \.self) { shape in
shape
.padding()
.background(Color.red)
}
}
关于ios - SwiftUI:可以管理各种形状协议(protocol)的单个结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63093327/