Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
UIライブラリは どう設計されるべきか
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
kazuhiro4949
October 13, 2017
Technology
3.2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
UIライブラリは どう設計されるべきか
iOSDC 2017 Reject Conference Days 1
https://iosdc-reject-conference.connpass.com/event/64175/
kazuhiro4949
October 13, 2017
More Decks by kazuhiro4949
See All by kazuhiro4949
SwiftUIをUIKitのライフサイクルで拡張するTips
kazuhiro4949
4
2.9k
iOS15でプッシュ通知のテストが大変だった話
kazuhiro4949
0
670
Source Editor Extensionと SwiftSyntaxでコード自動生成ツール を作る
kazuhiro4949
2
5k
iOS 12サポート終了で使えるAPIおさらい
kazuhiro4949
2
410
Source Editor ExtensionとSwiftSyntaxでコード自動生成
kazuhiro4949
0
140
大企業の最前線でコードを書き続けるためにやってきたこと
kazuhiro4949
27
19k
10分で振り返るここ数年のWWDCの技術トレンド
kazuhiro4949
0
360
コードを書きながら同時に設計していくためのiOSアプリ開発方針
kazuhiro4949
6
2.7k
身近な技術的課題から始めるOSSプロジェクト
kazuhiro4949
0
370
Other Decks in Technology
See All in Technology
NDIでApple Vision Proにリアルタイム映像送信
jyouryuusui
0
110
Claude Code本は、どのように執筆チームで書かれたか
oikon48
1
370
Optunaの最新リリースv5.0について
pfn
PRO
0
110
Local CI × GitHub Actions
gogutan
2
130
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
100
[JAWS-UG彩の国埼玉#12]そろそろ準備する?re:Invent2026をやさしく解説 / reinvent2026-sainokuni
sh_fk2
1
270
Snapshot Testing in Practice: Predictable and Reliable SwiftUI Views
fespinoza
0
220
夫婦で子育てするための育児標準化
codmoninc
PRO
0
210
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
740
分析AIエージェントを育てる、動く環境を育てる
codatum
1
1.1k
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.6k
ハードウェアコンペでもAI駆動開発が進んでいる話
iotengineer22
1
720
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
We Are The Robots
honzajavorek
0
400
WENDY [Excerpt]
tessaabrams
14
40k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
700
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
430
How to make the Groovebox
asonas
2
2.5k
KATA
mclloyd
PRO
35
16k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
560
Transcript
6*ϥΠϒϥϦ Ͳ͏ઃܭ͞ΕΔ͖͔ ,B[VIJSP)":"4)* J04%$3FKFDU$POGFSFODF%BZT
ࣗݾհ w ྛ߂ w 5XJUUFSɿLB[VIJSP w HJUIVCɿLB[VIJSP w RJJUBɿLB[VIJSP w
:BIPP+BQBO$PSQ w J04ΞϓϦΤϯδχΞ w J04ΞϓϦࠇଳ
ΞδΣϯμ w 6*ϥΠϒϥϦΛར༻ͯ͠։ൃ͢ΔதͰ໘ͨ͠ɺΫϥεͷ ࠶ར༻ੑʹର͢Δ՝ͷհ w ৽نʹ։ൃͨ͠ϥΠϒϥϦͰͲͷΑ͏ʹ՝Λղܾ͔ͨ͠ ղઆ w 6*ͷڞ௨ΫϥεΛઃܭ͢ΔࡍͷϙΠϯτΛཧ
J04ΞϓϦͷ6*ϥΠϒϥϦ w ͜͜Ͱɺ6*,JUͷΫϥεΛܧ ঝͨ͠ܗͰఏڙ͞ΕΔɺ࠶ར༻ ՄೳͳΫϥεΛѻ͏ w $PSF"OJNBUJPO $PSF(SBQIJDT $PSF5FYUͳͲ
ͷϨΠϠϑϨʔϜϫʔΫ ϑΥʔΧε͔Β֎͢ IUUQTEFWFMPQFSBQQMFDPNMJCSBSZDPOUFOUEPDVNFOUBUJPO$PDPB$PODFQUVBM$PSF"OJNBUJPO@HVJEF*OUSPEVDUJPO*OUSPEVDUJPOIUNM
͋ΔϓϩμΫτͷ
͋ΔϓϩμΫτͰϖʔδϯά6* ͷϥΠϒϥϦΛͬͯ։ൃ w 4NBSU/FXTNFSDBSJɺ :BIPPχϡʔεͰ࠾༻͞Εͯ ͍ΔΑ͏ͳɺϖʔδϯάͱԣε ΫϩʔϧϝχϡʔͷΈ߹Θͤ
ͦͷϥΠϒϥϦͰɺUJUMF͕ઃఆ͞Εͨ7$Λ"SSBZͰ ͢ͱɺܾ·ͬͨσβΠϯͷϖʔδϯά6*͕࡞ΒΕΔ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢ let ary: [UIViewController] = [ {
$0.title = "Page1" return $0 }(UIViewController()), { $0.title = "Page2” return $0 }(UIViewController()), { $0.title = "Page3" return $0 }(UIViewController()) ] pagingViewController.childViewControllers = ary
ͦͷϥΠϒϥϦͰɺUJUMF͕ઃఆ͞Εͨ7$Λ"SSBZͰ ͢ͱɺܾ·ͬͨσβΠϯͷϖʔδϯά6*͕࡞ΒΕΔ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢ let ary: [UIViewController] = [ {
$0.title = "Page1" return $0 }(UIViewController()), { $0.title = "Page2” return $0 }(UIViewController()), { $0.title = "Page3" return $0 }(UIViewController()) ] pagingViewController.childViewControllers = ary ϝχϡʔ͕͋Δ
ͦͷϥΠϒϥϦͰɺUJUMF͕ઃఆ͞Εͨ7$Λ"SSBZͰ ͢ͱɺܾ·ͬͨσβΠϯͷϖʔδϯά6*͕࡞ΒΕΔ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢ let ary: [UIViewController] = [ {
$0.title = "Page1" return $0 }(UIViewController()), { $0.title = "Page2” return $0 }(UIViewController()), { $0.title = "Page3" return $0 }(UIViewController()) ] pagingViewController.childViewControllers = ary ϖʔδϯάՄೳͳ ίϯςϯπྖҬ͕͋Δ
ελΠϧύϥϝʔλͰ͢͜ͱ͕Մೳ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ॳظͷγϯϓϧͳཁ݅Λຬ͍ͨͯͨ͠ w ϖʔδϯάͰ͖Δίϯςϯπ w εΫϩʔϧ͞ΕΔϝχϡʔ w ϝχϡʔʹλΠτϧ͕දࣔ͞Ε͍ͯ Δ w ݱࡏͷϖʔδҐஔͷϝχϡʔ͕ڧௐ͞
Εͯɺݱࡏ͕Θ͔ΔΑ͏ʹͳ͍ͬͯ Δ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
͔͠͠ཁ͕݅গͣͭ͠ෳࡶԽ͍͖ͯ͠ɺ ࠾༻ͨ͠ϥΠϒϥϦͰରԠ͖͠Εͳ͘ͳΔ
ϓϩμΫτͷʹͬͯ6*͕ࡉԽ͞Εɺ ͜͏͍ͬͨ͜ͱΛٻΊΒΕΔΑ͏ʹͳ͖ͬͯͨ w ྫ͑ w ͋Δը໘Ͱϝχϡʔͷಛ ఆͷཁૉͷ্ʹαϒλΠτ ϧΛ͚͍ͨ w ͋Δը໘Ͱίϯςϯπͱ
ϝχϡʔͷྖҬؒϘλϯ Λฒ͍ͨ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ϓϩμΫτͷʹͬͯ6*͕ࡉԽ͞Εɺ ͜͏͍ͬͨ͜ͱΛٻΊΒΕΔΑ͏ʹͳ͖ͬͯͨ w ྫ͑ w ͋Δը໘Ͱϝχϡʔͷಛ ఆͷཁૉͷ্ʹαϒλΠτ ϧΛ͚͍ͨ w ͋Δը໘Ͱίϯςϯπͱ
ϝχϡʔͷྖҬؒϘλϯ Λฒ͍ͨ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ར༻͍ͯͨ͠ϥΠϒϥϦͰ ཁ݅Λຬͨͤͳ͘ͳͬͯ͘Δ
৭ΜͳέʔεͰڞ௨ͰΘΕΔ6* ͲͷΑ͏ʹ࡞ΒΕΔ͖ͩΖ͏͔
͜ͷͭΛߟྀͯ͠ઃܭ͞Ε Δͱྑ͍ͷͰͳ͍͔ͱࢥ͏ ΠϯλϥΫγϣϯͷΈΛͱͯ࣋ͭ͠Ϋϥεʹ͢Δ ϨΠΞτมߋʹରͯ͠ग़དྷΔݶΓࣗ༝͕ߴ͍ঢ়ଶʹ ͢Δ ෦ίϯϙʔωϯτͷબɾஔࣗ༝Ͱ͋Δඞཁ͕͋Δ
BEE4VCWJFX @ BEE$IJME7JFX$POUSPMMFS @ ʹΑΔί ϯϙδγϣϯͰར༻Ͱ͖ΔΑ͏ʹ͢Δ
Ҏ্ͷߟ͑ํʹج͖ͮ ৽ن։ൃͨ͠ϥΠϒϥϦ
IUUQTHJUIVCDPNLB[VIJSP1BHJOH,JU 1BHJOH,JU
1BHJOH,JUͷಛ w ΠϯλϥΫγϣϯ෦ΛϥΠϒ ϥϦͰఏڙ w ϝχϡʔྖҬͱίϯςϯπྖҬ ͕࿈ಈͯ͠ಈ͘
1BHJOH,JUͷಛ w ϨΠΞτࣗ༝ʹܾΊΒΕΔ w ϝχϡʔͱίϯςϯπͷؒ ʹ7JFXΛڬΉ w ϝχϡʔͱίϯςϯπΛฒ ସ͑Δ
1BHJOH,JUͷಛ w தͷ7JFXίϯϙʔωϯτ ΞϓϦͰ༻ҙ͢Δ w ϝχϡʔͷσβΠϯΛม͑Δ w ϝχϡʔʹ6*-BCFMΛͭฒ ͨΓɺ6**NBHF7JFXΛஔ ͍ͨΓ͢Δ
͍ํ
w ҎԼͷ̎ͭͷ7JFX$POUSPMMFSΛ 4UPSZCPBSE্Ͱ$POUBJOFS7JFX ΛͬͯϨΠΞτ͢Δ w 1BHJOH.FOV7JFX$POUSPMMFS w 1BHJOH$POUFOU7JFX$POUSPMMFS 1BHJOH.FOV7JFX$POUSPMMFS 1BHJOH$POUFOU7JFX$POUSPMMFS
w 4FHVFͰઃఆͨ͠௨ৗͷ$IJME 7JFX$POUSPMMFSͱಉ͡Α͏ʹɺ ίʔυ্Ͱऔಘ͢Δ class ViewController: UIViewController { var menuViewController:
PagingMenuViewController! var contentViewController: PagingContentViewController! // … // ... override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let vc = segue.destination as? PagingMenuViewController { menuViewController = vc } else if let vc = segue.destination as? PagingContentViewController { contentViewController = vc } } } QSFQBSF GPSTFOEFS ͰTUPSZCPBSEͰઃఆ͠ ͨ7$ΛϓϩύςΟೖΕΔ
w ϝχϡʔͷཁૉʹ૬͢Δ7JFX ɺ1BHJOH.FOV$FMMΛܧঝ͠ ͯΞϓϦέʔγϣϯଆͰ༻ҙ͢ Δ w ΞϓϦͰͷڞ௨ͷελΠϧ ը໘ຖͷݸผͷελΠϧͰ ༻ҙ͢Δ ͜ͷதͷͦΕͧΕͷཁૉʹ
૬
w ಉ༷ʹϖʔδϯάதͷݱࡏҐஔ Λද͢Πϯδέʔλ 1BHJOH'PDVT7JFXΛܧঝͯ͠ ΞϓϦଆͰ༻ҙ͢Δ w ΞϓϦͰͷڞ௨ͷελΠϧ ը໘ຖͷݸผͷελΠϧͰ ༻ҙ͢Δ ݱࡏදࣔ͞Ε͍ͯΔҐஔΛ
ϝχϡʔ্Ͱදͨ͢ΊͷΠ ϯδέʔλ
var data: (menuTitle: String, vc: UIViewController) = [ (menuTitle: "test1",
vc: UIViewController()), (menuTitle: "test2", vc: UIViewController()), (menuTitle: "test3", vc: UIViewController()) ] w ը໘ʹද͍ࣔͤͨ͞ҙͷσʔ λΛ༻ҙ͢Δ w ϝχϡʔλΠτϧจࣈྻ ͷΈ w ίϯςϯπۭͷ7$Λ༻ҙ ͍ͯ͠Δ
w ϝχϡʔͷදࣔΛ࣮͢Δ w ༻ҙͨ͠σʔλΛ%BUB4PVSDF ܦ༝ͰɺඞཁͳλΠϛϯάͰ ฦ͢ w 5BCMF7JFX$PMMFDUJPO7JFXͱ ಉ༷ͳΈͰҎԼΛ͢ w
σʔλ w ηϧͷ෯ w σʔλΛόΠϯυͨ͠ηϧ // ϝχʔ෦ͷDataSource extension ViewController: PagingMenuViewControllerDataSource { func numberOfItemForMenuViewController( viewController: PagingMenuViewController) -> Int { return data.count } func menuViewController(viewController: PagingMenuViewController, widthForItemAt index: Int) -> CGFloat { return 100 } func menuViewController(viewController: PagingMenuViewController, cellForItemAt index: Int) -> PagingMenuViewCell { let cell = viewController.dequeueReusableCell(withReuseIdentifier: "MenuCell", for: index) as! MenuCell cell.titleLabel.text = data[index].menuTitle return cell } }
w ίϯςϯπͷදࣔΛ࣮͢Δ w ༻ҙͨ͠σʔλΛ%BUB4PVSDF ܦ༝ͰɺඞཁͳλΠϛϯάͰ ฦ͢ w 5BCMF7JFX$PMMFDUJPO7JFX ͱಉ༷ͳΈ w
σʔλ w σʔλΛόΠϯυͨ͠ 7JFX$POUSPMMFS // ίϯςϯπ෦ͷDataSource extension ViewController: PagingContentViewControllerDataSource { func numberOfItemForContentViewController( ɹ viewController: PagingContentViewController) -> Int { return data.count } func contentViewController(viewController: PagingContentViewController, viewControllerAt index: Int) -> UIViewController { return data[index].vc } }
w ৼΔ͍ͷΈΛ༷ͱͯ࣋ͭ͠ҎԼͷΫ ϥεΛίϯϙδγϣϯ͢Δ w 1BHJOH.FOV7JFX$POUSPMMFS w 1BHJOH$POUFOU7JFX$POUSPMMFS w ҎԼͷཁૉΞϓϦଆͰ༻ҙ͢Δ w
ϨΠΞτ w தʹԿΛදࣔͤ͞Δ͔
ྫ͑ͲͷΑ͏ͳཁ݅ ରԠͰ͖ΔΑ͏ʹͳ͔ͬͨ
ྫ͑ͲͷΑ͏ͳཁ݅ ରԠͰ͖ΔΑ͏ʹͳ͔ͬͨ w ϨΠΞτΛมߋͯ͠ϝχϡʔ ͱίϯςϯπͷؒʹΧςΰϦબ ϘλϯΛݻఆͯ͠ฒ͍ͨ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ྫ͑ͲͷΑ͏ͳཁ݅ ରԠͰ͖ΔΑ͏ʹͳ͔ͬͨ w ϝχϡʔͷҰ෦ཁૉʹ্෦ʹ ࠓɾ໌ͱ͍ͬͨऍΛ͚ͭ ͍ͨ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ྫ͑ͲͷΑ͏ͳཁ݅ ରԠͰ͖ΔΑ͏ʹͳ͔ͬͨ w ಈըͷϓϨΠϠʔ͕͋ͬͯɺͦ ͷ෦ϝχϡʔͱࣅͨΑ͏ͳ ײ͡ͷಈ͖ͷ6*Λ࡞ͬͯཉ͍͠ ˞Πϝʔδ ࣮ࡍʹؔΘͬͨϓϩμΫτͱҧ͍·͢
ҎԼͷ݅Λҙࣝ͢Δ͜ͱͰɺ࠶ར༻ੑ Λҡ࣋ͭͭ͠Ϋϥεͷڞ௨Խ͕Ͱ͖ͨ ΠϯλϥΫγϣϯͷΈΛͱͯ࣋ͭ͠Ϋϥεʹ͢Δ ϨΠΞτมߋʹରͯ͠ग़དྷΔݶΓࣗ༝͕ߴ͍ঢ়ଶʹ ͢Δ ෦ίϯϙʔωϯτͷબɾஔࣗ༝Ͱ͋Δඞཁ͕͋Δ
BEE4VCWJFX @ BEE$IJME7JFX$POUSPMMFS @ ʹΑΔί ϯϙδγϣϯͰར༻Ͱ͖ΔΑ͏ʹ͢Δ
·ͱΊ w ڞ௨ΫϥεΛ։ൃ͢Δ࣌࠶ར༻ੑͷ؍ͰΛҙࣝ͢Δɻ࣮ͷ γϯϓϧ͞ͱॊೈੑ௨ৗτϨʔυΦϑͳͷͰόϥϯεΛݟۃΊΔ w J04Ͱ6*,JUͷϨΠϠʹڞ௨ΫϥεΛߏங͢Δ߹ɺΠϯλϥΫγϣ ϯͷΈΛنఆ͢Δͷ͕ྑ͍ w ϨΠΞτɺΠϯλϥΫγϣϯͷ༷Λյ͞ͳ͍ఔͰग़དྷΔݶΓ ࣗ༝͕ߴ͍ͱྑ͍
w ෦ίϯϙʔωϯτͷஔͦͷελΠϧΞϓϦʹ·͔ͤͯؔ༩͠ ͳ͍ͷ͕ྑ͍
ࢀߟࢿྉ w 6*,JUc"QQMF%FWFMPQFS%PDVNFOUBUJPO w IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOVJLJU w $PODFQUTJO0CKFDUJWF$1SPHSBNNJOH w IUUQTEFWFMPQFSBQQMFDPNMJCSBSZDPOUFOUEPDVNFOUBUJPO(FOFSBM$PODFQUVBM $PDPB&ODZDMPQFEJB*OUSPEVDUJPO
w LB[VIJSP1BHJOH,JU w IUUQTHJUIVCDPNLB[VIJSP1BHJOH,JU w ϝϧΧϦεϚϗͰ͔ΜͨΜϑϦϚΞϓϦ w IUUQTXXXNFSDBSJDPNKQ w :BIPPχϡʔεެࣜΞϓϦ:BIPPχϡʔε w IUUQTOFXTZBIPPDPKQQSPNPBQQZKOFXT w 4NBSU/FXT w IUUQTXXXTNBSUOFXTDPNKB