Skip to content

Instantly share code, notes, and snippets.

@davideme
Last active June 13, 2019 17:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davideme/efb614251fc1b783b405628a7002333b to your computer and use it in GitHub Desktop.
Save davideme/efb614251fc1b783b405628a7002333b to your computer and use it in GitHub Desktop.
struct List : View {
var body: some View {
NavigationView {
List(viewModel.superHeroes.identified(by: \.name)) { value in
SwitchValue(value) {
CaseType(is: SuperHero.self) { superHero in
Text(superHero.name)
}
CaseType(is: Avenger.self) { avenger in
Text(avenger.name).color(.red).bold()
}
}
}
.navigationBarTitle(Text("Kata Super Heroes"))
}
}
}
@_functionBuilder
class ViewByTypeBuilder {
public static func buildBlock(_ viewByType: CaseType<Any, AnyView>) -> [String: (Any) -> AnyView] {
return [viewByType.type: viewByType.content]
}
public static func buildBlock(_ viewByType: CaseType<Any, AnyView>, _ viewByType2: CaseType<Any, AnyView>) -> [String: (Any) -> AnyView] {
return [viewByType.type: viewByType.content, viewByType2.type: viewByType2.content]
}
}
struct CaseType<Value, Content: View> {
let type: String
let content: (Any) -> AnyView
init<Value, Content: View>(is: Value.Type, @ViewBuilder builder: @escaping (Value) -> Content) {
self.type = "\(`is`)"
self.content = { (value: Any) -> AnyView in
AnyView(builder(value as! Value))
}
}
}
struct SwitchValue: View {
private let value: Any
private let bindings: [String: (Any) -> AnyView]
init(_ value: Any, @ViewByTypeBuilder builder: () -> [String: (Any) -> AnyView]) {
self.value = value
self.bindings = builder()
}
var body: some View {
let typeKey = "\(type(of: value))"
return self.bindings[typeKey]!(value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment