Monaca UG Conference 2019で発表したスライドです。 https://monacaug.mobi/conference-2019/
仮想スクロールとダークモードについては、以下記事で詳細をまとめています。併せてどうぞ。
仮想スクロール https://qiita.com/kishisuke/items/d00862008fc90163f55b
ダークモード https://qiita.com/kishisuke/items/e1fecb20d35693680421
MonacaΞϓϦΛωΠςΟϒͷUXʹ͚ۙͮΔͨΊʹDaisuke KishinoMonaca UG Conference 20192019.10.26
View Slide
ࣗݾհ• ϐʔϓϧιϑτΣΞגࣜձࣾ• ؛ େี(@kishisuke)• Ԭࢁݝෑࢢࡏॅ• ͜͜2BaaS@rakuza+MonacaΞϓϦͷ։ൃ(Vue.jsϝΠϯ)• ༗ࢤͰIoTσόΠεͷ։ൃ(RaspberryPi+JS+Python)• Monaca UG OKAYAMAͬͯ·͢
MonacaΞϓϦ͍ͬͯͬͯݴΘΕͨ͜ͱͳ͍Ͱ͔͢ʁ
࣮ࡍͷͱ͜ΖجຊతʹUI/UXωΠςΟϒ ʼ Monaca(Cordova/WebView)ͩͱࢥ͍·͢ɻ͍͚͘͠Ͳ
Monacaͷྑ͍ͱ͜Ζ• ։ൃίετ͕͍ͱ͜Ζʢ1ιʔεɺWebܥͷਓࡐଟʣ• αʔϏεͷ্ཱ͛࣌ɺࢁͷΞϓϦΛ։ൃ͢Δ࣌ʹ༗རߴ͍։ൃίετΛ͔͚ͯແཧΓωΠςΟϒͷUXΛࢦ͢ͱຊస
ͦ͜Ͱ
MonacaͰ͖ΔൣғͰBetterͳUI/UXΛࢦ͢ํ๏ʹ͍ͭͯ͠·͢ʂ
λʔήοτ• Monacaͷ։ൃΛ͍ͯͯ͠ɺ໘ͷνϡʔχϯάΛ͍ͨ͠ํ• MonacaΛಋೖ͍͚ͨ͠ͲɺUI/UXͷ৺͕͋Δํ
ΞδΣϯμ• جຊฤ• جຊతͳςΫχοΫΛհ• Ԡ༻ฤ• ωΠςΟϒΞϓϦͷτϨϯυΛհ
جຊฤجຊతͳςΫχοΫΛհ
ͷલʹ
ͦͦྑ͍UXͬͯʁ• ࣗʢϢʔβʔʣͷࢥ͍௨Γʹಈ͔͘ʁ• ʮ͍ʯͰͳ͘ʮࢥ͍௨Γʹͳ͍ͬͯͳ͍ʯͨΊΠϥΠϥ͍ͯ͠ΔʁϢʔβʔ͕ظ͢Δಈ͖ʹͳΕྑ͍
Ͱຊ
ඇಉظॲཧ
ѱ͍ྫ
ɾϑΟʔυόοΫ͕ͳ͍ɾϦϑϩʔ͕ෳͬͯΧΫπΫɾϢʔβʔͷૢ࡞ΛϒϩοΫ͍ͯ͠Δɾϩʔυ͕ྃ͢Δ·Ͱɺଞͷը໘Λ։͚ͳ͍
ྑ͍ྫ
ɾͯ̍͢ճͰදࣔɾϓϩάϨείϯςϯπ෦ʹදࣔɾߴ͞ΛݻఆʢϦϑϩʔͷࢭʣ
φϏήʔγϣϯ
ɾͯ͢ͷϖʔδ͕DOMπϦʔʹΔɾݟ͍͑ͯͳ͍ϖʔδdisplay: noneʹͳΔͨΊɺϨϯμʔπϦʔ͔Βআ͞ΕΔɹରԠࡦɾແݶભҠ͠ͳ͍༷ʹ͢Δɾ֤ը໘ͷDOMπϦʔͷαΠζΛݮΒ͢ʢԾεΫϩʔϧͳͲʣɾΞϓϦશମͰ1ͭͷφϏήʔγϣϯʹ͢Δ
ԾεΫϩʔϧ
Ұཡ͋Δ͋Δ• ͯ͢ϨϯμϦϯάͯ͠͠·͏• σʔλ͕ઍ݅͋ͬͯ…• 20݅ͣͭϖʔδϯά͠ͳ͕ΒಡΈࠐΉͷख• ҰಡΈࠐΉͱDOMπϦʔ্ʹΔͷͰɺͲΜͲΜ͘ͳΔ
ԾεΫϩʔϧ(vue-virtual-scrollerͷྫ)• Viewport(ݟ͑Δ෦)ͷItemͷΈϨϯμϦϯά• εΫϩʔϧ࣌ʹͲͷItem͕Viewportʹೖ͔ͬͨΛܭࢉ• ViewportʹೖͬͨItemΛϨϯμϦϯά• Viewport͔Β֎ΕͨItemΛআ
Viewport(ݟ͑Δ෦)Item
Viewport͕ҠಈʢεΫϩʔϧ͞ΕͨʣViewport֎ʹͳͬͨͨΊϨϯμʔπϦʔ͔ΒআViewportʹͳͬͨͨΊϨϯμϦϯάϨϯμʔπϦʔͷߴ͕͞มΘΔͱΧΫπΫ
Ϧετશମ(min-heightͰߴ͞Λݻఆ)Itemtransform: translateYͰදࣔҐஔΛௐʢදࣔҐஔ͕ݻఆʹͳΔͨΊɺΧΫ͔ͭͳ͍ʣ
Itemͷߴ͕͞Մมͷ߹• Ұ୴ɺԾͷߴ͞ͰܭࢉΛߦ͍ɺItemͷϨϯμϦϯάޙʹߋ৽͢Δ• Itemͷߴ͞Ωϟογϡ͢Δ
Ҿͬுͬͯߋ৽
• iOSͰҾͬுͬͯߋ৽ΛUIΛ࣮Λ͢ΔͱͪΒͭ͘• UIWebViewͷόά
ղܾࡦWKWebViewΛ͏
WKWebViewΛ͏• ϋοΫͰղܾͰ͖ͳ͍͜ͱͳ͍͕ɺਅͬͳखஈͰղܾͨ͠ํ͕Α͍• 2019/8͔ΒɺUIWebViewΛϦϯΫ͍ͯ͠ΔΞϓϦΛAppStoreʹఏग़͢Δͱɺܯࠂ͕දࣔ͞ΕΔΑ͏ʹͳͬͨ
ଞʹؾΛ͚ͭΔ৭ʑ• ࣮ػͰࣗͰ৮ͬͯҧײ͕ͳ͍͔ɺࢥ͍௨Γʹͳ͍ͬͯΔ͔ɺ։ൃऀࣗͰ֬ೝ͢Δͷ͕ྑ͍• ͜͏͍͏࣌MonacaͷσόοΨʔศར
Ԡ༻ฤωΠςΟϒΞϓϦͷτϨϯυΛհ
ͳͥτϨϯυ͔ʁ”4.2 ࠷ݶͷػೳAppΛ࡞͢ΔࡍɺWebαΠτΛ୯ʹ࠶ύοέʔδͨ͠Α͏ͳͷͰͳ͘ɺ༏ΕͨػೳɺίϯςϯπɺUIΛ࡞͢ΔΑ͏ʹ͍ͯͩ͘͠͞ɻಛʹศརͰɺϢχʔΫͰɺʮAppΒ͘͠ʯͳ͍߹ɺͦͷAppΛApp StoreͰఏڙ͢Δ͜ͱͰ͖·ͤΜɻ”App Store ReviewΨΠυϥΠϯΑΓ
ͳͥτϨϯυ͔ʁ• ʮAppΒ͘͠ʯͷج४ʑมΘ͍ͬͯΔ• τϨϯυʹ͍͍͔ͯͳ͍ͱɺʮAppΒ͘͠ʯແ͘ͳͬͯ͠·͏Մೳੑ
Fluid Interfaces
ࢥߟͷԆͷ༷ʹײ͡ΔΠϯλʔϑΣʔε
Redirectable
iPhone 8 (Not Redirectable) iPhone X (Redirectable)
Not Redirectable=ߟ͔͑ͯΒಈ͔͢ߟ͑Δ ܾఆ͢Δ ಈ͔͢ ͢
Redirectable=ߟ͑ͳ͕Βಈ͔͢ߟ͑Δ ܾఆ͢Δಈ͔͢ ͢ਓߟ͑ͳ͕Βಈ͘ੜ͖UIRedirectableͰ͋ΕɺࢥߟͷԆͷ༷ʹײ͡Δ
ྫ)YouTubeϥΠΫͳUI• ಈը෦ΛԼʹҾͬுΔͱด͡Δ• λονΠϕϯτ(touchmove)ͰҠಈ͚ͨͩ͠ɺtransform: translateYͳͲͷελΠϧΛมߋ
YouTubeϥΠΫͳUIͷࣦഊஊ• ಈը෦ͷαΠζΛheight/widthͰมߋ͓ͯ͠ΓɺϦϑϩʔ͞Εͯݹ͍ͩͱ͕ΧΫπΫ…• transformͱopacity͚ͩมߋ͢ΔΑ͏ʹͨ͠• ಈըscaleͰॖখ• ಈըΑΓԼtranslate: transformYͰҐஔΛௐ• Γ͗͢ײ
ϋʔϑϞʔμϧ• iOS13͔Βඪ४ͱͳͬͨUI• UIͷཁ݅తʹϨΠΞτมߋ͕ෆཁ• ͜Ε͙Β͍Ͱ͋Εɺൺֱత؆୯ʹ࣮Ͱ͖ΔͷͰɺ࠾༻ͯ͠ྑ͍͔
μʔΫϞʔυ
Ionicਪͷํ๏͕Αͦ͞͏• ϝσΟΞΫΤϦʔ(prefers-color-scheme)ͷΛݩʹɺΫϥεͰϑΥʔϧόοΫ• ॳճϝσΟΞΫΤϦʔ͔ΒݱࡏͷςʔϚ(dark/light)Λऔಘ• ςʔϚมߋ࣌ͷΠϕϯτϋϯυϥΛొͯ͠ɺมߋ࣌ΫϥεΛΓସ͑Δ• ݹ͍iOSରԠͰ͖ΔɺखಈͰมߋͰ͖Δhttps://ionicframework.com/docs/theming/dark-mode
mounted() {this.$ons.ready(() => {// prefersDark.matches=trueͷ߹ɺμʔΫϞʔυconst prefersDark = window.matchMedia('(prefers-color-scheme: dark)')// ݱࡏͷϞʔυʹมߋthis.changeTheme(prefersDark.matches)// ϞʔυͷมߋΛݕprefersDark.addListener((mediaQuery) => this.changeTheme(mediaQuery.matches))})},methods: {changeTheme(dark) {// μʔΫϞʔυͷ߹ɺbodyʹ"dark"ΫϥεΛ༩document.body.classList.toggle('dark', dark)}}
AndroidͷWebViewͩͱಈ͔ͳ͍
AndroidରԠ• AndroidWebViewࣗମϏϡʔͷςʔϚʹґଘ͢Δ• WebViewWebSettings#setForceDarkͰมߋՄೳͳΑ͏͕ͩɺมΘΒͳ͍ʢAndroidͷόάʁʣ• CordovaϓϥάΠϯΛ࡞ͯ͠ωΠςΟϒAPIΛࢀরͯ͠ղܾ
ղܾ͕ͨ࣌͠ظঘૣײ• ຊདྷWebͰͰ͖Δ͜ͱͳͷʹɺϓϥάΠϯԽ͕ඞཁ• ݱ࣌ͰɺMonacaରԠ͍ͯ͠ͳ͍• Xcode11ɺAndroid API Ϩϕϧ 29͕ඞཁ
ͦΕͰಋೖ͢ΔϝϦοτΛߟ͑Δྫ͑…
؍ޫΞϓϦ༻࣌ؒ͘ಛఆͷʹ͔͠༻͠ͳ͍༻͕࣌ؒ͘μʔΫϞʔυΛಋೖ͢Εʹ༏͍͠Ϛετυϯ(SNS)ͷΞϓϦଟগίετϦεΫ͋ͬͯಋೖ͢ΔϝϦοτ͋Δʂ
τϨϯυٕज़ͷಋೖ৻ॏʹ• ·ͣαϯϓϧΛ࣮͢Δ• อकίετͱϝϦοτΛఱṝʹ͔͚ͯಋೖΛݕ౼• CordovaϓϥάΠϯ͠ͳ͍ͱͰ͖ͳ͍ʂԫ৭৴߸
·ͱΊ
·ͱΊ• جຊΛԡ͑ͯ͞ɺϢʔβʔͷࢥ͍௨Γʹಈ͘Α͏ʹ͢Δ• ωΠςΟϒͷUI/UXਐԽ͢ΔͷͰɺτϨϯυʹ͍͍ͯ͘͜ͱॏཁ• ͍͖ͳΓಋೖͰͳ͘ɺίετͱͷ݉Ͷ߹ΘͤΛߟྀͯ͠গͮͭ͠࠾༻͢Δগ͠ͰMonacaΞϓϦͷUI/UXʹΛ͚͍͚ͯͨͩΕʂ