Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftUI Viewの責務分離
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
elmetal
PRO
February 18, 2025
Programming
530
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SwiftUI Viewの責務分離
elmetal
PRO
February 18, 2025
More Decks by elmetal
See All by elmetal
The Integrity of Making: Extending Xcode Previews with MCP
elmetal
PRO
0
38
Generating DocC with AI
elmetal
PRO
0
71
A Swift Way to Blog
elmetal
PRO
0
200
Designing DocC for Clarity and Beauty
elmetal
PRO
0
130
サイボウズiOSアプリのマルチモジュール 2024
elmetal
PRO
0
150
開発を加速する共有Swift Package実践
elmetal
PRO
0
1.4k
Resolve Nested ObservableObject issues in Observation
elmetal
PRO
0
440
ObservationSallowDive
elmetal
PRO
1
390
「サイボウズ Office」 の iOSアプリをリニューアルした話 / Renewal "Cybozu Office" iOS App
elmetal
PRO
0
760
Other Decks in Programming
See All in Programming
FDEが実現するAI駆動経営の現在地
gonta
2
270
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
150
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
340
今さら聞けない .NET CLI
htkym
0
180
What's New in Android 2026
veronikapj
0
250
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
860
Foundation Models frameworkで画像分析
ryodeveloper
1
600
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
630
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
730
プロポーザルを書いてもらう
pvcresin
0
290
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
140
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
160
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
340
How to make the Groovebox
asonas
2
2.3k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Making the Leap to Tech Lead
cromwellryan
135
10k
Google's AI Overviews - The New Search
badams
0
1.1k
How to build a perfect <img>
jonoalderson
1
5.9k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Making Projects Easy
brettharned
120
6.7k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
490
Transcript
4XJGU6*7JFXͷ .PCJMF"$504"," FMNFUBM
"CPVUNF !FM@NFUBM@ J04"QQ %FWFMPQFS ڝഅ ରઓήʔϜ ҭࣇ ෳνʔϜͷ ٕज़ࢧԉ
4XJGU6*7JFXେ͖͘ͳΓ͕ͪ
ͨͩͷϦετ 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) } } }
αʔόʔ͔ΒσʔλΛ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 } } } } }
σʔλ͕݅ͷέʔεΛՃ 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 } } } }
௨৴ΤϥʔͷέʔεΛՃ 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 } } } }
ओཁ෦͕͍ΒΕ͍ͯ͘ 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 } } } } ओཁ෦͜Ε͚ͩ
7JFXͷׂ
ίʔφʔέʔεΛ 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ϒϩοΫ
$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") } } } } } ۭྻ ωοτϫʔΫΤϥʔ
ۭྻͷදࣔఆٛଆͰߦ͏ 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") } } } }
ۭྻͷදࣔఆٛଆͰߦ͏ 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")) } } } } } }
એ
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
2"
͋Γ͕ͱ͏͍͟͝·ͨ͠