Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SwiftUI Viewの責務分離

elmetal
February 18, 2025

SwiftUI Viewの責務分離

elmetal

February 18, 2025
Tweet

More Decks by elmetal

Other Decks in Programming

Transcript

  1. ͨͩͷϦετ struct ContentView: View { @State var pokemons: [Pokemon] =

    [Pokemon(name: "Sprigatito"), Pokemon(name: "Fuecoco"), Pokemon(name: "Quaxly")] var body: some View { NavigationView { PokemonList(data: pokemons) .listStyle(.grid) } } }
  2. αʔόʔ͔ΒσʔλΛGFUDI͢Δ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] var body: some View { NavigationView { PokemonList(data: pokemons) .listStyle(.grid) .task { do { pokemons = try await PokeRepository.mock.fetch() } catch { // some errors } } } } }
  3. σʔλ͕݅ͷέʔεΛ௥Ճ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] var body: some View { NavigationView { if pokemons.isEmpty { Text("no pokemons") } else { PokemonList(data: pokemons) .listStyle(.grid) } } .task { do { pokemons = try await PokeRepository.mock.fetch() } catch { // some errors } } } }
  4. ௨৴ΤϥʔͷέʔεΛ௥Ճ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] @State var error: MyError? var body: some View { NavigationView { if let error { switch error { case .network: Text("network error") } } else if pokemons.isEmpty { Text("no pokemons") } else { PokemonList(data: pokemons) .listStyle(.grid) } } .task { do { pokemons = try await PokeRepository.mock.fetch() self.error = nil } catch { self.error = .network } } } }
  5. ओཁ෦෼͕௥͍΍ΒΕ͍ͯ͘ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] @State var error: MyError? var body: some View { NavigationView { if let error { switch error { case .network: Text("network error") } } else if pokemons.isEmpty { Text("no pokemons") } else { PokemonList(data: pokemons) .listStyle(.grid) } } .task { do { pokemons = try await PokeRepository.mock.fetch() self.error = nil } catch { self.error = .network } } } } ओཁ෦෼͸͜Ε͚ͩ
  6. ίʔφʔέʔεΛ෼཭ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] @State var error: MyError? var body: some View { NavigationView { PokemonList(data: pokemons) .listStyle(.grid) .task { do { pokemons = try await PokeRepository.mock.fetch() self.error = nil } catch { self.error = .network } } .overlay { if let error { switch error { case .network: Text("network error") } } else if pokemons.isEmpty { Text("no pokemons") } } } } } ΤϥʔΛPWFSMBZϒϩοΫ΁
  7. $POUFOU6OBWBJMBCMF7JFXΛར༻ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] @State var error: MyError? var body: some View { NavigationView { PokemonList(data: pokemons) .listStyle(.grid) .task { do { pokemons = try await PokeRepository.mock.fetch() self.error = nil } catch { self.error = .network } } .overlay { if let error { switch error { case .network: ContentUnavailableView("network error", systemImage: "wifi.slash", description: Text("check your internet connection")) } } else if pokemons.isEmpty { ContentUnavailableView("no pokemons", systemImage: "circle") } } } } } ۭ഑ྻ ωοτϫʔΫΤϥʔ
  8. ۭ഑ྻͷදࣔ͸ఆٛଆͰߦ͏ struct GridPokeListStyle: PokeListStyle { var columns = [GridItem(.adaptive(minimum: 80),

    spacing: 16)] func makeBody(configuration: PokeListConfiguration) -> some View { ScrollView { LazyVGrid(columns: columns, spacing: 16) { ForEach(configuration.pokemons, id: \.self) { pokemon in PokemonView(pokemon: pokemon) } } .padding([.horizontal], 16) } .overlay { if configuration.pokemons.isEmpty { ContentUnavailableView("no pokemons", systemImage: "circle") } } } }
  9. ۭ഑ྻͷදࣔ͸ఆٛଆͰߦ͏ struct ContentView: View { @State var pokemons: [Pokemon] =

    [] @State var error: MyError? var body: some View { NavigationView { PokemonList(data: pokemons) .listStyle(.grid) .task { do { pokemons = try await PokeRepository.mock.fetch() self.error = nil } catch { self.error = .network } } .overlay { if let error { switch error { case .network: ContentUnavailableView("network error", systemImage: "wifi.slash", description: Text("check your internet connection")) } } } } } }