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

HTMLコーダーよSwiftUIれ 〜型を制する者はすべてを制す〜

C6860c38adec703e995505b9afa12c83?s=47 yumemi
March 03, 2021

HTMLコーダーよSwiftUIれ 〜型を制する者はすべてを制す〜

どこで発表すればいいのかわからない技術LT会 第1回 で発表したスライドです。
結論から申しますと、HTMLとSwiftUIはとてもよく似ています。きちんとHTMLを書けるならば、SwiftUIもすぐに書けることでしょう。

でも、いきなりそんなことを言われてもピンと来ませんよね。試しにシンプルなTODOアプリを作って見比べてみましょう。

ああ……、なんということでしょう。index.htmlContentView.swift は、ほとんど同じではありませんか。

例えばHTMLでいうdiv要素は、SwiftUIでは、内包するビューを水平方向に並べて表示するHStackというビューを使って表現することができます。HStackは display: flex; 付きのdiv要素のようなものです。
さらに、データの一覧は、HTMLではul要素で実装しますが、SwiftUIでは同じようにListビューを使います。
そういうわけでHTMLコーダーはSwiftUIをすぐに理解できます!ぜひやりましょう!

……でも、疑問ですよね。なぜ似ているから簡単にできるなどというのでしょう。それから、なぜこれほどラフなイメージから、HTMLでもSwiftUIでも作ってみることができたのでしょう。
そもそも、なぜコーダーはカンプから実装できるのでしょう。なぜデザイナーは意味不明な案件でデザインできるのでしょう。なぜユーザーは初めて見たアプリケーションを操作できるのでしょう。

それは、ユーザーインターフェイスにも型があるからだと考えられます。UIの型とは、ひとびとがUIを認識する共通の仕方のことです。例えばデザインならば利用のコンテキストや想定するユーザーのコンテキスト、コーディングであれば一覧の表示やスタイルの付与、操作であれば入力や検索など、現代のひとびはUIについて共通した認識の仕方や、感じ取り方を持っています。
上手いコーダーは、デザイナーが提示したカンプを見て、UIの型、すなわち「これはユーザーにとって何として認識されるのか」を考えて実装することができます。

そういうわけで、UIの型を知り、きちんとHTMLを書けるならば、SwiftUIでも問題なくコードを書くことができます。ぜひやりましょう!

C6860c38adec703e995505b9afa12c83?s=128

yumemi

March 03, 2021
Tweet

Transcript

  1. ʙܕΛ੍͢Δऀ͸͢΂ͯΛ੍͢ʙ ど ͜ で ൃද͢Ε ば ͍͍ͷ͔Θ͔Βͳ͍ٕज़-5ձ  ZVNFNJ )5.-ίʔμʔΑ4XJGU6*Ε

  2. ໊લ ZVNFNJʢΏΊΈʣ ࢓ࣄ 6*σβΠϯ αʔϏεσβΠϯ σβΠϯίϯαϧςΟϯά ࢿ֨ )5.-ϓϩϑΣογϣφϧೝఆϨϕϧ ΍͍͖ͬͯ )5.-

    $44 +BWB4DSJQU 7VFKT 4XJGU 4XJGU6* 3VCZPO3BJMT 1ZUIPO
  3. None
  4. IUUQTHJUIVCDPNOZVNFNJIVNBOJUJFTMU@XFC

  5. IUUQTHJUIVCDPNOZVNFNJIVNBOJUJFTMU@TXJGUVJ

  6. શମ var body: some View { HStack { Text("TODO") .font(.title)

    .fontWeight(.bold) Spacer() } .padding() HStack(alignment: .center, spacing: 8) { TextField("΍Δ͜ͱ", text: $text) .textFieldStyle(RoundedBorderTextFieldStyle()) Button(action: { addTodo() }){ Text("௥Ճ") } .buttonStyle(primaryButtonStyle()) } .padding() List { ForEach(todos.indices, id: \.self) { index in HStack { Text(todos[index]) Spacer() Button(action: { removeTodo(index: index) }){ Text("׬ྃ") } .buttonStyle(primaryButtonStyle()) } } } } } <body> <div id="app"> <header class="header"> <h1 class="title">TODO</h1> </header> <main class="main"> <div class="add-todo"> <input class="todo-text" type="text" placeholder="΍Δ͜ͱ" v-model="newTodo"> <input class="button" type="button" value="௥Ճ" v-on:click="addTodo"> </div> <ul class="list-todo"> <li v-for="(todo, index) in todos" v-bind:key="todo.id"> <p class="text">{{ todo.text }}</P> <button class="button" v-on:click="removeTodo(index, todo)">׬ྃ</button> </li> </ul> </main> </div> </body> JOEFYIUNM $POUFOU7JFXTXJGU
  7. var body: some View { HStack { Text("TODO") .font(.title) .fontWeight(.bold)

    Spacer() } .padding() HStack(alignment: .center, spacing: 8) { TextField("΍Δ͜ͱ", text: $text) .textFieldStyle(RoundedBorderTextFieldStyle()) Button(action: { addTodo() }){ Text("௥Ճ") } .buttonStyle(primaryButtonStyle()) } .padding() List { ForEach(todos.indices, id: \.self) { index in HStack { Text(todos[index]) Spacer() Button(action: { removeTodo(index: index) }){ Text("׬ྃ") } .buttonStyle(primaryButtonStyle()) } } } } } <body> <div id="app"> <header class="header"> <h1 class="title">TODO</h1> </header> <main class="main"> <div class="add-todo"> <input class="todo-text" type="text" placeholder="΍Δ͜ͱ" v-model="newTodo"> <input class="button" type="button" value="௥Ճ" v-on:click="addTodo"> </div> <ul class="list-todo"> <li v-for="(todo, index) in todos" v-bind:key="todo.id"> <p class="text">{{ todo.text }}</P> <button class="button" v-on:click="removeTodo(index, todo)">׬ྃ</button> </li> </ul> </main> </div> </body> JOEFYIUNM $POUFOU7JFXTXJGU શମ
  8. <header class="header"> <h1 class="title">TODO</h1> </header> HStack { Text("TODO") .font(.title) .fontWeight(.bold)

    Spacer() } .padding() JOEFYIUNM $POUFOU7JFXTXJGU λΠτϧ .header > .title { font-size: 1rem; font-weight: 700; } DPNNPODTT
  9. <div class="add-todo"> <input type="text" class="todo-text" placeholder="΍Δ͜ͱ" v-model="newTodo"> <button class="button" v-on:click="addTodo">௥Ճ</button>

    </div> HStack(alignment: .center, spacing: 8) { TextField("΍Δ͜ͱ", text: $text) .textFieldStyle(RoundedBorderTextFieldStyle()) Button(action: { addTodo() }){ Text("௥Ճ") } .buttonStyle(primaryButtonStyle()) } .padding() JOEFYIUNM $POUFOU7JFXTXJGU ೖྗͱϘλϯ
  10. <ul class="list-todo"> <li v-for="(todo, index) in todos" v-bind:key="todo.id"> <p class="text">{{

    todo.text }}</P> <button class="button" v-on:click=“removeTodo(index)">׬ྃ</button> </li> </ul> List { ForEach(todos.indices, id: \.self) { index in HStack { Text(todos[index]) Spacer() Button(action: { removeTodo(index: index) }){ Text("׬ྃ") } .buttonStyle(primaryButtonStyle()) } } } JOEFYIUNM $POUFOU7JFXTXJGU Ϧετ
  11. ΄΅΄΅͍ͬ͠ΐ΍Μ͚ ŋТŋ 

  12. w ͳΜͰ͜Μͳϥϑ͔Β࣮૷Ͱ͖ͨΜͩΖ͏ w ͳΜͰಈ͖·Ͱ૝૾Ͱ͖ΔΜͩΖ͏ w ͳΜͰ)5.-Ͱ΋4XJGU6*Ͱ΋࡞ΕͨΜͩΖ͏ ͯΏʔ͔ɺͦ΋ͦ΋Ͱ͢Α

  13. w ͳͥίʔμʔ͸Χϯϓ͔Β࣮૷Ͱ͖Δͷ͔ w ͳͥσβΠφʔ͸;Θ;ΘͳҊ͔݅ΒσβΠϯͰ͖Δͷ͔ w ͳͥϢʔβʔ͸ॳΊͯݟͨΞϓϦΛૢ࡞Ͱ͖Δͷ͔ ΋ͬͱɺͦ΋ͦ΋Ͱ͢Α

  14. 6*ʹ΋ܕ͕͋Δ ͻͱ͸໨ʹݟ͑Δ΋ͷΛʰͳʹ͔ʱͱͯ͠ೝࣝ͢Δɻ ҙຯෆ໌ͳҊ݅ͷͳ͔ͰɺσβΠφʔ͸ೝࣝ͢΂͖ܗΛ͜ͷੈʹఏࣔ͢Δɻ ্ख͍ίʔμʔ͸ɺఏࣔ͞Εͨ΋ͷ͕ʮ͜Ε͸Ϣʔβʔʹͱͬͯͳʹ͔ʯΛߟ࣮͑ͯ૷͢Δɻ ܕΛ஌Βͳ͍ίʔμʔ͸EJWͱTQBO͚ͩͰੜ͖Δɻ σʔλʹܕ͕͋ΔΑ͏ʹɺ6*ʹ΋ܕ͕͋Δɻ 6*ͷܕͱ͸ɺͻͱͼͱʹΑͬͯ͞ΕΔڞ௨ͷೝࣝͷ࢓ํͰ͋Δɻ ͦ͏͍͏Θ͚ͰίʔμʔΑʂ6*ͷܕʹ໨֮ΊΑ͏ʂ4XJGU6*Λ΍Ζ͏ʂ ʢٯ΋Մʣ ㅟ

    ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ