Slide 1

Slide 1 text

4XJGU6*7JFXͷ੹຿෼཭ .PCJMF"$504"," FMNFUBM

Slide 2

Slide 2 text

"CPVUNF !FM@NFUBM@ J04"QQ %FWFMPQFS ڝഅ ରઓήʔϜ ҭࣇ ෳ਺νʔϜͷ ٕज़ࢧԉ

Slide 3

Slide 3 text

4XJGU6*7JFXେ͖͘ͳΓ͕ͪ

Slide 4

Slide 4 text

ͨͩͷϦετ 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) } } }

Slide 5

Slide 5 text

αʔόʔ͔ΒσʔλΛ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 } } } } }

Slide 6

Slide 6 text

σʔλ͕݅ͷέʔεΛ௥Ճ 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 } } } }

Slide 7

Slide 7 text

௨৴ΤϥʔͷέʔεΛ௥Ճ 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 } } } }

Slide 8

Slide 8 text

ओཁ෦෼͕௥͍΍ΒΕ͍ͯ͘ 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 } } } } ओཁ෦෼͸͜Ε͚ͩ

Slide 9

Slide 9 text

7JFXͷ੹຿෼ׂ

Slide 10

Slide 10 text

ίʔφʔέʔεΛ෼཭ 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ϒϩοΫ΁

Slide 11

Slide 11 text

$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") } } } } } ۭ഑ྻ ωοτϫʔΫΤϥʔ

Slide 12

Slide 12 text

ۭ഑ྻͷදࣔ͸ఆٛଆͰߦ͏ 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") } } } }

Slide 13

Slide 13 text

ۭ഑ྻͷදࣔ͸ఆٛଆͰߦ͏ 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")) } } } } } }

Slide 14

Slide 14 text

એ఻

Slide 15

Slide 15 text

4XJGU6*7JFX$PEJOH(VJEFMJOFT https://github.com/cybozu/swiftui-view-coding-guidelines https://cybozu.github.io/swiftui-view-coding-guidelines/documentation/swiftuiviewcodingguidelines/ %PD$ (JU)VC3FQP

Slide 16

Slide 16 text

2"

Slide 17

Slide 17 text

͋Γ͕ͱ͏͍͟͝·ͨ͠