如何优化swiftui中的switch case
How to optimize switch case in swiftui
我有一个视图可以根据传入的参数显示不同的样式
有50多种不同的风格,每种风格都有冲突的布局。我想根据传入的样式显示不同的样式
我要写50多个案例如下:
struct StyleDefaultView: View {
let style: Int
var body: some View {
VStack() {
Text("111")
}
}
}
struct Style1View: View {
let style: Int
var body: some View {
HStack() {
VStack() {
Text("111")
}
Text("222")
}
}
}
struct Style2View: View {
let style: Int
var body: some View {
VStack() {
Text("111")
HStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style3View: View {
let style: Int
var body: some View {
HStack() {
Text("111")
VStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style4View: View {
let style: Int
var body: some View {
HStack() {
Text("222")
VStack() {
Text("111")
Text("111")
}
Text("111")
}
}
}
// ... other 50+ style
struct ContentView: View {
let style: Int
var body: some View {
VStack() {
switch style {
case 1:
Style1View(style: style)
case 2:
Style2View(style: style)
case 3:
Style3View(style: style)
case 4:
Style4View(style: style)
// case .. other 50+ style
default:
StyleDefaultView(style: style)
}
}
}
}
有没有办法简化这些 swift 案例代码?类似于 Java 中的反射,如下代码
struct ContentView: View {
let style: Int
let viewMap = [
0 : "StyleDefaultView",
1 : "Style1View",
2 : "Style2View",
3 : "Style3View",
// ... other 50 views
]
var body: some View {
let viewName: String = viewMap[style] ?? "StyleDefaultView"
// initialization a view by a string
viewName(style : style)
}
}
编辑:
这只是一个让您考虑循环不同样式视图的示例:
struct StyleDefaultView: View {
var body: some View {
VStack() {
Text("111")
}
}
}
struct Style1View: View {
var body: some View {
HStack() {
VStack() {
Text("111")
}
Text("222")
}
}
}
struct Style2View: View {
var body: some View {
VStack() {
Text("111")
HStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style3View: View {
var body: some View {
Text("1112")
Text("1112")
Text("1112")
}
}
struct Style4View: View {
var body: some View {
Text("1112")
Text("1")
}
}
class StyleViewModel {
let styles: [AnyView] = [
AnyView(Style1View()),
AnyView(Style2View()),
AnyView(Style3View()),
AnyView(Style4View())]
func selectedStyleView(_ ndx: Int) -> AnyView {
if ndx < styles.count {
return styles[ndx]
} else {
return AnyView(StyleDefaultView())
}
}
}
struct ContentView: View {
let styles = StyleViewModel()
let style: Int = 2
var body: some View {
styles.selectedStyleView(style)
}
}
我认为更好的方法是使用每个协议都符合的协议。然后你只需要存储类型,这意味着它真的很轻量级,因为你没有实例化一堆你可能不需要使用的视图。
例子
首先,ContentView
这样您就可以主要了解正在发生的事情。这是一个带有 Slider
的交互式示例,因此您可以更改样式以对其进行测试。
struct ContentView: View {
private static let styleTypes: [StyledView.Type] = [
StyleDefaultView.self,
Style1View.self,
Style2View.self,
Style3View.self,
Style4View.self
]
@State private var currentStyle = 0
var body: some View {
VStack {
Text("Style: \(currentStyle)")
Slider(
value: Binding<Double>(
get: { Double(currentStyle) },
set: { currentStyle = Int([=10=]) }
),
in: 0 ... 4,
step: 1
)
Spacer()
Self.styleTypes[currentStyle].init().buildView()
}
}
}
结果(还有其余代码):
协议:
protocol StyledView {
init()
func buildView() -> AnyView
}
extension StyledView where Self: View {
func buildView() -> AnyView {
AnyView(self)
}
}
现在您需要做的就是使每个视图符合 StyledView
,无需在每个视图中编写额外的代码。第一视图示例(但对所有视图都执行此操作):
struct StyleDefaultView: View, StyledView {
var body: some View {
VStack() {
Text("111")
}
}
}
旁注:VStack
不需要那些 ()
因为你有尾随闭包。
我有一个视图可以根据传入的参数显示不同的样式
有50多种不同的风格,每种风格都有冲突的布局。我想根据传入的样式显示不同的样式
我要写50多个案例如下:
struct StyleDefaultView: View {
let style: Int
var body: some View {
VStack() {
Text("111")
}
}
}
struct Style1View: View {
let style: Int
var body: some View {
HStack() {
VStack() {
Text("111")
}
Text("222")
}
}
}
struct Style2View: View {
let style: Int
var body: some View {
VStack() {
Text("111")
HStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style3View: View {
let style: Int
var body: some View {
HStack() {
Text("111")
VStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style4View: View {
let style: Int
var body: some View {
HStack() {
Text("222")
VStack() {
Text("111")
Text("111")
}
Text("111")
}
}
}
// ... other 50+ style
struct ContentView: View {
let style: Int
var body: some View {
VStack() {
switch style {
case 1:
Style1View(style: style)
case 2:
Style2View(style: style)
case 3:
Style3View(style: style)
case 4:
Style4View(style: style)
// case .. other 50+ style
default:
StyleDefaultView(style: style)
}
}
}
}
有没有办法简化这些 swift 案例代码?类似于 Java 中的反射,如下代码
struct ContentView: View {
let style: Int
let viewMap = [
0 : "StyleDefaultView",
1 : "Style1View",
2 : "Style2View",
3 : "Style3View",
// ... other 50 views
]
var body: some View {
let viewName: String = viewMap[style] ?? "StyleDefaultView"
// initialization a view by a string
viewName(style : style)
}
}
编辑:
这只是一个让您考虑循环不同样式视图的示例:
struct StyleDefaultView: View {
var body: some View {
VStack() {
Text("111")
}
}
}
struct Style1View: View {
var body: some View {
HStack() {
VStack() {
Text("111")
}
Text("222")
}
}
}
struct Style2View: View {
var body: some View {
VStack() {
Text("111")
HStack() {
Text("111")
Text("111")
}
}
Text("222")
}
}
struct Style3View: View {
var body: some View {
Text("1112")
Text("1112")
Text("1112")
}
}
struct Style4View: View {
var body: some View {
Text("1112")
Text("1")
}
}
class StyleViewModel {
let styles: [AnyView] = [
AnyView(Style1View()),
AnyView(Style2View()),
AnyView(Style3View()),
AnyView(Style4View())]
func selectedStyleView(_ ndx: Int) -> AnyView {
if ndx < styles.count {
return styles[ndx]
} else {
return AnyView(StyleDefaultView())
}
}
}
struct ContentView: View {
let styles = StyleViewModel()
let style: Int = 2
var body: some View {
styles.selectedStyleView(style)
}
}
我认为更好的方法是使用每个协议都符合的协议。然后你只需要存储类型,这意味着它真的很轻量级,因为你没有实例化一堆你可能不需要使用的视图。
例子
首先,ContentView
这样您就可以主要了解正在发生的事情。这是一个带有 Slider
的交互式示例,因此您可以更改样式以对其进行测试。
struct ContentView: View {
private static let styleTypes: [StyledView.Type] = [
StyleDefaultView.self,
Style1View.self,
Style2View.self,
Style3View.self,
Style4View.self
]
@State private var currentStyle = 0
var body: some View {
VStack {
Text("Style: \(currentStyle)")
Slider(
value: Binding<Double>(
get: { Double(currentStyle) },
set: { currentStyle = Int([=10=]) }
),
in: 0 ... 4,
step: 1
)
Spacer()
Self.styleTypes[currentStyle].init().buildView()
}
}
}
结果(还有其余代码):
协议:
protocol StyledView {
init()
func buildView() -> AnyView
}
extension StyledView where Self: View {
func buildView() -> AnyView {
AnyView(self)
}
}
现在您需要做的就是使每个视图符合 StyledView
,无需在每个视图中编写额外的代码。第一视图示例(但对所有视图都执行此操作):
struct StyleDefaultView: View, StyledView {
var body: some View {
VStack() {
Text("111")
}
}
}
旁注:VStack
不需要那些 ()
因为你有尾随闭包。