iPhone アプリを自分でつくる 9.
今回の内容: SwiftUIを見てみる
今回はSwiftUIをのぞいてみます。
Xcodeの確認
前回作成したProjectを開いてください。
File - Open でファイル名TestApp1を選択するか File - OpenRecent でTestApp1をクリックして開くことができます。
開くとContenView.swiftが選択されてエディター画面が開きます。
もし拡張子.swiftの表示がない場合は、左上のXcode - Settings - General - FileExtensions のShowAll を選択すると表示されるようになりますが、表示されていなくてもかまいません。
Canvasの表示
右にはCanvasの欄が開いていてPreview pausedとなっていたらマル矢印①でResume(復帰)を行なってください。
もしCanvasが開いていなければ前回を参考に開いてから復帰してください。
また表示機種を選ぶには下にあるiPhone 型のアイコンをクリックしてポップアップから ② 選択します。
Canvas 左下の青丸三角印①はPlayボタンです。
コードを追加したら念のためこのボタンかResumeをクリックしてください。初期化されてコードが走ります。
また右下にある拡大ルーペ②で拡大、その左にあるルーペ③でそのときのスペースにフィットしたサイズで表示してくれます。
その下にある下ラインのついた四角アイコン④でエラーやprint表示がされるコンソール部分を表示させることができます。
Canvas での debug エリア表示について
以前はCanvas では print() させても debug エリアに表示できなかったように思うのですが、現在はしたのほうのPreviews を切り替えておけば表示できるようです。
シミュレータや実機を立ち上げるとExecutable に切り替わってしまうので、その後にCanvas でprint() を調べるときはこのタブを再度切り替えます。
Canvas を表示したくないとき
シミュレーターを使用したりViewではない(表示に関係ない)コードをかいている場合などCanvas を表示させたくないときがあります。
右上のエディターアイコン①をクリックして Canvas のチェックを外す②か、
コードの最後にある #Preview { } の部分③をコメントアウトするか消去すれば
Canvas は表示されません。
シミュレーターで表示する場合
シミュレーターはXcode から立ち上げるものの 別アプリになっています。Canvas は今書いているコードのデザインを見るのが主になりますが、アプリの全体像を確認するときはシミュレーターを起動します。
なお、シミュレーターを立ち上げるとCanvas はポーズ(ストップ)します。
またシミュレーターのところに自分のiPhoneなどを登録すれば自分の端末で動かすこともできます。今後機会を見てご説明していきます。
シミュレーターを立ち上げます。
まず機種を選択します。
Xcode 上部の真ん中にあるトンカチマーク①をクリックするとシミュレーターの機種選択画面がポップアップされます。
自分の機種が登録されていると上の方にiOS Devices としてでてきます。②
今後機会をみて扱います。
その下のBuild とあるのは、ビルド(翻訳し使えるようにしておく)のためだけなので、特に関係ないと思ってもらって結構です。(アプリをAppStoreに提出するときには使用しますが、通常立ち上げようとしてもエラーとなります)
その下がiOS Simulators とありここから機種を選択します。③
右にある数字は、iOSのバージョンです。
このnote ではiOS Ver. 17.0以上で動くコードを使う予定ですが、いまのところどれを選んでいただいても結構です。
選択が完了したらPlay ボタンをクリックして立ち上げます。④
シミュレーターの表示サイズはコーナーの部分をドラッグして変えることができます。⑤
シミュレーターの上にはホームボタン⑥、スクリーンコピー⑦、端末ローテーション(Orientation)⑧ があります。
なお、通常の操作(下からスワイプしてホーム画面など)もマウスなどを使用してもできますので遊んでみてください。
なお機種も沢山あって立ち上げることはできますが、使うのは2~4種類ぐらいに絞ったほうが良いと思います。(iPhone、iPad またそのサイズ違いなど)
というのは、その機種のテンポラリーファイルが少しづつ溜まって意外と大きなサイズになる可能性があるためです。
私は500G のMacBook Pro を使用していますが、多くの機種を立ち上げたためだと思うのですが2年に1度くらいXcodeのテンポラリーファイルを掃除しました。
(5分ぐらいの作業ではありますが、ファイルを触るのが嫌な方はイヤだろうとおもいます。)
閉じる時は四角いストップボタン⑨をクリックしてから端末左上の赤丸で表示を消します⑩
ストップボタンを使用せずに赤丸ボタンだけでも良いですが、画面下にエラーメッセージとして「回線が途切れました」とでます。⑪
このメッセージは特に問題ありませんが、一応上の手順(⑨ ⑩)で実施したほうが良いかと思います。(そういう私はいつも忘れてプチッとしてしまいますが。)
ContentView.swiftのコードを見てみる
では最初から表示されているコードを見ていきましょう。
この段階(まだコードを書く前の段階)で言葉で説明しても非常にわかりにくいですし、ピンとこないほうが普通だと思います。(すくなくとも私はそうでした。)
ただこの後コードを書いていく中で、疑問に思ったときに「この部分に関連することかな」と推測できるように雰囲気をつかんでいければよいと思います。
8 import SwiftUI
9
10 struct ContentView: View {
11 var body: some View {
12 VStack {
13 Image(systemName: "globe")
14 .imageScale(.large)
15 .foregroundStyle(.tint)
16 Text("Hello, world!")
17 }
18 .padding()
19 }
20 }
21
22 #Preview {
23 ContentView()
24 }
1行目から6行目あたりまでは、自動的に付加されるコメント行です。
いつごろ作成したかなど後から参考にできるものですが、修正したり消してもコードには影響しません。
8行目 import SwiftUI でコードが始まります。
アプリを作っていくときにはこのようなファイルを何枚もつくっていきます。
なおファイルでview(画面の表示に関係ある部品)を扱わない時は SwiftUI の機能の一部 import Foundation にすることもありますし、地図を扱うときはimport Mapkit を追加することもあります。
この後にご説明するstruct(構造体) やクラス、enum を作成してその中にコード書いていきますが、それ以外に書くとエラーがでます。
下の例のようにすると「通常のコードはトップレベルには記入できません」と表示されます。
トップレベルとあるようにここに記入する内容はこのファイル全体に関わるコードとなります。
playground ではファイル自体がすでにコードのまとまりとして設定されていました(つまり白紙の裏にはすでになんらかの(トップレベルの)コードが書かれていました)が、これからは、本当の白紙にコードを書いていきます。
白紙に import SwiftUI とすることでプログラミングコードが始まります。
もとに戻しますが、10行目には struct ContentView: View { とあります。
structはストラクト(構造体)と呼ばれ、「ひとつのまとまりですよ」というものです。 ※ 詳しくは第6回のType(型)を確認してください。
10行目から20行目が構造体としてのまとまりとなっています。
それは { } の位置で判別できます。
ContentView(コンテントビュー)がこの構造体の名前です。
この名前のコードが最初に読まれるように(画面に現れるように)初期設定がしてあります。ContentViewにコロン:で繋げられたViewというのは画面に表示させるためのView型ルール(View プロトコル)で書かれていますよ、を意味しています。
※ 詳しくは第7回のプロトコル を確認してください。
11行目に var body: some View { とあります。これはViewプロトコル(ルール)として記入するもので画面に表示させる内容(view)はこのbody変数の中に記入することになっています。
bodyはsome View 型という型で View型に適合した部品を入れていきます。型名のすぐ後ろに { }があるのはコンピューティッドプロパティだからです。
bodyは11行目から19行目です。これも{ } の位置で判別できます。
12行目から18行目にbodyの内容(content)が記入されています。
※参考 body はcontent が返してくるview を受けとりますが、下記のreturn は省略して書かれます。(普通このような書き方はしません)
var body: some View {
return VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
12行目から17行目はVStackがラップしていて、この範囲の中身は縦置きに表示しますよ、というコードです。18行目にある.padding()はVStackを修飾する機能で上下左右に少しスペースを開ける機能をもちます。
.padding() の詳細は今後取り上げていきますが、大きな括りではViewプロトコルの持つメソッドのひとつです。Viewプロトコルは多くの種類の修飾子(メソッド)を持っていて ImageやText などのviewにくっつけることができます。
くっついて包んで修飾してくれます。修飾子は小さいように見えますがviewをやさしく包んでくれる大きな心を持つ親なのです。
なお今回の場合 .padding() はVStack についていますが、中のImageやTextに影響を及ぼしています。
13行目 Image(systemName: "globe")とあるのはImage型イメージを表示します、"globe"の名前で登録されたシステム画像を出してください、ということです。またこのsystemName とあるのは、システム登録されているアイコンを呼び出す方法です。
14、15行目はImage型の持つ機能を使って画像を装飾しています。
Apple 公式のSF Symbols をダウンロードしておくととても役に立ちます。
すべて Image(systemName: " 〜 ”) でここに載っているアイコンを表示させることができます。もちろん無料です。
16行目はText("Hello, world!")でText型テキストで文字列"Hello, world!"を表示させてください、ということです。
※ VStack はブイスタックと呼びVertical Stackバーティカルスタック:縦に積むと言う意味。
HStack はエイチスタックと呼ぶHorizontal Stack ホリゾンタルスタック:横に並べる構造体もあります。
VStack やHStack は部品(view となるコード)を中に入れるのでコンテナとも呼ばれます。
Indentインデントについて
コードを調べて気づいたと思いますが、コードのまとまりは大きな括りの中に小さなまとまりを入れていきます。これを入れ子構造と言います。
大きい親の中にだんだん小さな子供が入っていく構造です。
そしてこの構造が一目でわかるようにIndentインデントを設定します。
Indentとは字下げとも呼ばれます。
Swiftでは、ひとつ上の親よりも4つ分文字を後ろにした位置に記入します。
まとまりの最初と最後の列は同じになるよう記入するので一目でまとまりがわかるのです。
22行目から24行目は#Previewプレビューですが中に ContentView()と書かれています。
これは上にあるContentView()を読み取って右のCanvasに表示させる役割をもっています。
シミュレーターや実機への表示はPreViewに関わりませんので必要ない場合には消去しても問題ありません。
(というのもプログラミングは複雑になってくるとPreview を表示させるのも難しくなってくるのですが、Preview のエラーだけのせいで立ち上がらない(翻訳してくれない)こともよくあります。その場合は消えていただくことになります。
話が少し戻りますが、var body: some View { } の内容を消してみるとエラーがでます。例では var body の内容をコメントアウトしています。
3つのエラーとも結果同じことを言っていて「変数body は some View 型(なんらかのView型を返す[opaque return type]型)なのにそれらしいものは見つからないよ」いうことです。
このような状況は今後コードを書き進める中で普通に発生します。
大量のエラーがでると最初はビックリしますが少し慣れてくると「これから書こうとしていたのに!わかっとるわい!」とイラッとします。
しかしもっと慣れてくると、次はこんなエラーがでて、そこでこうして・・・と予測しながら書いていくようになります。
確かに Xcodeは私たちがどんなに頑張ってより良いコードを書いても決して褒めてはくれません。
でも本当にミスしたときにはいち早く教えてくれる良いやつなんです。
だから・・・だから・・・ 嫌いにならないで下さい!
え〜、元に戻って、例えば } を多く記入するとエラーがでます。
下図①は最後に } を追加してみたときのエラーです。
エラーは最後の行で「トップレベルに余分な } があるよ」と表示されました。
これはわかりやすいですね。
下図②はstruct の途中、真ん中あたりに } を入れてみました。
そうすると今度は2つのエラーがでてきました。
ひとつは、Expected declaration が .padding() の行についていますが、「期待する宣言がない」つまり「.padding() は何らかのview につくはずなのに見当たらないな〜」ということです。
そして最後21行目には「余分な } があるよ」と言ってます。
このような感じで、 } を間違えた際にどのようなエラーがでるかを見慣れておくと
対応が早くなります。(私ですか? 10万回ぐらい見てますので大丈夫です!)
上記②については、システムが次のような判断でエラーを出しています。
VStack は12行目から15行目だと判断している。
.foregroundStyle() はVStack を修飾すると思っている。
Text("Hello, world!") はVStack などのコンテナには入っていないので、画面上に上手い具合に配置しようとする。
18行目の } は、body の終了のカッコだと判断する。
.padding() が body についてしまうので、システムは「期待するような宣言がない」とエラーを出す。
20行目の } が struct の終了と判断する。
21行目の } は Extraneous(余分な)カッコとなる。
今度は } を減らしてみます。
17行目の } を消去してみたところ「サーキュラー・レファレンス(循環参照)がPreview のマクロに影響してるよ」とでてきました。
この場合は struct の終了が 24行目の } になってしまったので、ContentViewの中で ContentView() をイニシャライズしようとする状態(循環参照と言う困った状態)になってしまったということです。
Navigator について
左上のNavigator のアイコンをクリックするとNavigator の表示・非表示が切り替えられます。①
アプリ名 + App.swift の名前のファイル②をクリックして内容をみると @main ③とあります。これがプログラムの開始場所を宣言するものです。
中には ContentView() ④とありますが、さきほどのContentViewファイルで書かれたコードをここで初期化(使う・見える化)することがわかります。
参考までですが ContentViewという名前を(双方のファイルとも)変えて使用することもよく見られます。
Assetes.xcassets (アセッツ・エックスシー・アセッツ)ファイル ⑤ を開きます。(xc というのはXcodeの頭文字ですね。長い間 エックス・カセッツと思ってました。)
Accent Color ⑥は 画面のベースの色やダークモードの設定、その他の色の初期設定の変更などができます。コードでも同様の設定はできます。
AppIcon ⑦アップアイコン はアプリのアイコンを登録するものです。機会があれば取り上げていきます。
TestApp1 (作った名前)プロジェクト
一番上にあるプロジェクト名① を選択します。
TARGETS にある TestApp1(作った名前) ②をクリック
Generalタブ③をクリックします。
Destination ④デスティネーション(使用する端末のこと) 通常は放っておいても大丈夫です。たとえば iPad では絶対に使用しないアプリであれば選択してマイナス記号で削除すれば端末の種類の制限ができます。
Minumum Deployments ⑤ ミニマムディプロイメンツ(iOSの最低使用可能バージョン) これを18にすると最新のバージョンしか使えず iOSバージョン17以下の端末では「使用できません」となります。低いバージョンにすれば昔の端末でも使えるようにできますが、新しいコードが使えないケースが発生します。
しばらくは特に気にしなくてよいですが、今後の説明で iOS17以上でお願いする場合もある予定です。
Deployment Info ⑥ ディプロイメントインフォ iPhone、iPad それぞれで縦向き横向き、どちらの向きで(Orientation オリエンテーション と言います)使えるようにするかを決めます。
まとめ
アプリを作る準備が整ってきました。
少しづつプログラミングを進めていきましょう!
次回第10回内容 SwiftUIを書いてみる
もし余裕があれば下記参考資料をお読みください。
参考
定義の調べ方
SwiftUI を使用しているときに用語の定義を調べるときには、Quick Help ①が便利かと思います。
最初は内容がよくわからないかもしれませんが、知っている用語を見つけただけでもOK です。②
ああ〜なんか関係しているんだな〜でOK です。
もっと調べたいかたは Definition に飛んでください。
先ほどの右クリックから Jump to Definition を選択します。③
検索して出てくる場所が見たいところの一番下だったりするので、上下を読んでみてください。④
定義もバージョンで違ったりextension(第7回参考)について書かれていたりで読むのも大変ですが何かを伝えようとしている雰囲気を味わうだけでも大丈夫です!
この定義からもどるのは左上にある < ⑤からもとの場所に戻れます。
var body に返す値について
var body は content(内容) が返してきた some View型(なにかしらのview )を持ちます。
VStack や HStack はコンテナとして中にあるview :今回の例では Image() と Text()、それらをひとつの TupleView としてContentView に渡します。
※Tuple は data をまとめて返すものですが、第6回の「返す値が複数ある関数」の中でTuple について簡単に説明しています。そのSwiftUI 版ですね。
もしVStack やHStack などのコンテナがない場合でも 自動的に ViewBuilder ビュービルダー と言うものが働いて、view はひとつにまとめられます。
なおsome View 型とは、なんらかのView型 opaque return type オパーク・リターンタイプ(「はっきりしないものを返す型」という意味)を返す型です。
例えばText() であればテキスト型、 Image() であればイメージ型を返しますが、それらはそれぞれ「View プロトコルに適合しているね。OK!」とチェックされて始めてステージに上がれるのです。
今回は以上です。次回もよろしくお願いします。
この記事が気に入ったらサポートをしてみませんか?