【じっくりSw1ftUI32】実践編2〜第17章 SwiftUIモードでのXcode15の使用〜SwiftUIの開発環境(プラットフォーム)Xcodeを動かしてみよう🕺
さてと、前回
で
SwiftUIの概要
についてはまとめたつもりなので〜〜〜今回は、いよいよ
SwiftUIでアプリを作る開発環境(プラットフォーム)=Xcode
を動かしていく🕺
Canvas
LivePreview
デバッグ
などなど様々な機能があって、
知っておくと色々と便利な機能も多い
+
パフォーマンスが雲泥の差
になるので、ここも
💃読み飛ばさずにしっかりやってく🕺
👉こんなところは読み飛ばしても、どうせ使っていれば馴れる
みたいに思い込む人もいるけど、
案外使わずに一生知らない人も出てくるのでしっかりやる!
=そのために、オイラは学び直してるところもあるので〜〜〜
ま、今回の学び直しなんかもいらないって人は
で本文はそのまま公開されてるみたいなので、そちらでどうぞ〜〜〜
さてと、
じっくり第16章を読んでく
まずは、
SwiftUIでの環境での開発は、
UIKitでストーリーボードでやるのと大きく異なる
ってことを言ってんね👀
※UIKitでの開発を知りたい人は、【徒然iOS】マガジン
の
【気ままにUIKit】シリーズ
で、しっかりまとめてるつもりだから、そちらを参考にしてみてね!
なんかでも書いてるとおり、
SwiftUIを知るともはやUIKitでの開発には戻れない
👉マジで機能を改修する作業コストが面倒臭い
(コーディングベースではない全てのローコードツールでも言えることだけどね👀💦)
なので。次章以降で触れてく各モディファイアをUIKitの各パーツなんかと比較するのも面白いとは思うけど。
SwiftUIだと不要なOutletやAction接続なんかも必要になってきて面倒臭い
ってのが
肌感覚で分かる
と思う。ま、生真面目で努力と暗記バカが多い日本の自称、職人さんたちからは、
いや、両方使えるべき
両方知っておいて当然
積み上げが必要だから、UIKitを使いこなせないとSwiftUIは使いこなせない
なんて思い込みが聞こえてきそうなんだけど、
単純にSwiftUIもUIKitも、XcodeでiOSアプリを開発する際に利用するフレームワークが違うだけで、別にUIKitが使える前提でSwiftUIは開発されてるなんてこたあない
👉どのフレームワークを使うかだけの違い
=いきなりSwiftUIだけ学んでアプリ開発して全然OK
SwiftUIにない一部の機能だけUIKitで使えばいい程度
なんで、
勝手な思い込みとか使命感で、自分の学習コストを2〜3倍に跳ね上げないでね💦(勝手な職人像で余計な遠回りをしてる個人や企業が日本には本当に多い)
でも書いたとおり、
1冊にまとまったロクな技術書すら作れないくせにね、、、💦
Xcode15でSwiftUIモードを使おう
Xcode自体がまだ自分のMacに入っていないって人はいないとは思うんだけど(いたら、どうやって今までやってたシンタックス編までを動かしていたのか?🧐とは思ってしまうけど、、、💦)もし入っていないなら、
のリンク先の過去の記事なんかに、
Xcodeのインストール方法なんかはまとめてるから参考にしてみてね
インストールされたら、ドックなんかに追加したXcodeのアイコンをクリック
てな感じで
直感的に先に進んでいく
と、いつもどおり開発するプロジェクトができる🕺
ここでポイント1:マルチプラットフォーム=複合的に対応した開発環境なので
iOS
WatchOS
MacOS
tvOS
にも対応してる。しかも、最小限のコードの変更で、
最初はiOSなんかで作ったプロジェクトを別のOSに簡単に変更できる
(@_@)知らんかった、、、
BundleするURLなんかはリバースさせたものが出てくるって
Xcodeだと今までどおりの当たり前の作法
もちゃんと書いてあんね👀
ここでポイント2:画面の構成としては、
各エリアの名前としては、
A:プロジェクトナビゲーター
B:コードエディター
C:プレビューキャンパス
D:アトリビュートインスペクター
E:コンソールエリア
でさらに、そいつらの役割としては〜〜〜
A:プロジェクトナビゲーター = プロジェクト内のファイルを管理
B:コードエディター = 実際に組み込む作業をする
C:プレビューキャンパス = シミュレータや実機を使わずに動作検証できる
D:アトリビュートインスペクター = 色やサイズ各状態などをコードを打たずに編集できる
E:コンソールエリア = 実行時にPrintなんかで処理を見れる
てな感じだね。ちなみに、
キャンパス自体も
ここでポイント3:各エリアは自分で使いやすいようにカスタマイズできる
コード作業なんかに集中したい時は〜〜〜
なんかもクリックして、CanvasやMinimapのチェックも外してあげると
MacBook Airとか使っていて画面が小さい時にどうしてもプレビューとかが邪魔で作業が捗らない時とか、Canvasが常に動いていて、待機時間がうざいなんてときには使ってみてね〜〜〜
ここでポイント4:Canvas内の構成
次は、プレビュー画面が表示されるCanvasの中の構成に入ってく👀
ここも冒頭のリンクから、図を流用するけども
A:キャンバスエリア
B:サイズボタン
C:ピンボタン
D:プレビューツールバー
って名前で、各機能としては
A:キャンバスエリア = 現在のビューを表示する
B:サイズボタン = 表示の拡大や縮小、100%なんかにする
C:ピンボタン = 同じファイルに複数のプレビューなんかが
D:プレビューツールバー = プレビューの詳細機能切り替え
って感じ。例えば、ビューを同じファイルに一個増やして、
import SwiftUI
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
}
.padding()
}
}
#Preview{
SubView()
}
てな感じで、サブビューを一個追加して
コンテントビューで表示を固定したい時に〜〜〜
さてと次は、プレビューエリアの各詳細機能の切り替え
を紹介してく🕺ここも冒頭のリンク記事の図を流用して〜〜〜
プレビューの詳細機能
名前としては、
A:ライブモード
B:選択モード
C:バリアントボタン
D:ローテートボタン
E:デバイス切り替え
って感じ。そこに簡単な説明を付けると、
A:ライブモード = シミュレーターとか実機を使わずに実際の動きを確認
B:選択モード = ライブではなくあくまでもビュー単体で確認
C:バリアントボタン = 色合いとか文字サイズなんかを切り替え
D:ローテートボタン = 縦向きや横向きなどを切り替え
E:デバイス切り替え = iPhoneやiPadなんかの各機種を選択する
実際に動かしてく
ここでポイント5:ここはオイラの経験談だけど
⒈ふたつ前の画像と今の画像を比較してもらいたいんだけど、機種が変わった=画面サイズが違うはずなのに、どちらも文字がちゃんと中央に表示できてる👉これはVStackってモディファイアをコードで入れてるのもあるんだけど、
・Objective-CとかUIKit
(StackViewControllerを使わない限りは)
AutoLayoutって自分で各機種の画面サイズごとに位置やサイズ、アスペクト比なんかを細かく設定しないといけなかった
=結構、これが沼る作業でここでiOS開発を断念する人も多かった
↓
・SwiftUI
AutoLayoutという概念がなくなった
👉よりシンプルでモダンにビューを簡単に作れるようになった
⒉これまでの記事で書いたコードテンプレートを自分で実際に動かした人はお気付きだと思うけど、
ライブビューでも、リストから他のビューに遷移するアプリの場合は、実機かシミュレーターで動かさないと、リストから先に遷移しない
なんてことも多いから、
ライブビューでやってるのに、想定してる動きにならない
👉自分の組み方が何かおかしいんだろうか?
って考えて、コードと睨めっこしてうんうん唸るより先に、
シミュレーターや実機で動かしてみてね。
実は、コンテントビューから行かないと次の画面が開かないってことも多い
(理由は簡単なんだけど、他の章の話をしてからの方が理解しやすいと思うのでここではまだやらない笑)
とりあえず、次に行くので
ここでポイント6:SwiftUIで作業するってことは
以下を含んで作業してるってことらしい
ビュー追加
モディファイアを使ったロジックを追加
双方向性な宣言と他のデータインスタンスへの結びつけ
👉コードエディターの中でモディファイアと構築でやっていける
と、ここで
ここでポイント7:モディファイアって(今回から急に出てきたけど)何?
って人もいると思うので〜〜〜
って意味らしいんだけど、オイラ的には、
いい感じにする!
って感じ。それを実際に今から見ていく〜〜〜今までで作ってるサブビューだと、
これを
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
.font(.title)//追加
}
.padding()
}
}
#Preview{
SubView()
}
すると〜〜〜
これがモディファイア
👉自分のデザインしたい感じに調整する機能
ってイメージ。で、コードベースなんで、
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
.font(.title)
Text("こんにちは、SwiftUI🥺")
.font(.largeTitle)
Text("こんにちは、SwiftUI🥺")
.font(.title2)
Text("こんにちは、SwiftUI🥺")
.font(.title3)
Text("こんにちは、SwiftUI🥺")
.font(.caption2)
}
.padding()
}
}
#Preview{
SubView()
}
てな感じで、
と、今追加したコードは削除して
お次は、ビューの構築
例えばテキストビューをもうひとつ追加するとしたら、コードでさっきみたいにできなくはないし、馴れてくるとそっちが楽ではあるんだけど、
ここで、さっき出てきた
アトリビュートインスペクター
を開いて、
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
.font(.title)
Text(/*@START_MENU_TOKEN@*/"おはこんばんちは、アラレちゃん"/*@END_MENU_TOKEN@*/)
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.red)
}
.padding()
}
}
#Preview{
SubView()
}
てな感じのコードを追加してくれて〜〜〜
ここでポイント8:Jump to Definitionを使う
ライブラリに入ってる各ビューを追加したまではいいんだけど、そのビューの詳細を確認したい時にどうする?
よくXcodeの機能自体を理解してなくて、コードを打てるからなんとなく理解しただけの人で多い回答が、
WEBで調べる
本で調べる
Apple公式サイトで確認する
だと思うんだけど
WEBで調べる(じゃ、検索でヒットしなかったらどうする?)
本で調べる(使ってる本が古くて最新の情報がなかったらどうする?)
Apple公式サイトで確認する(そこで理解できなかったらどうする?)
そこで使えるのが、
Jump to Definition
例えば、さっき追加したTextビューの詳細を知りたい時に、
これはUIKitでも同様に使える機能で重宝するので〜〜〜
でも、【気ままにUIKit】シリーズで具体的な組み込みをやる前に
で書いてたりする。
他にも本文では、
再利用できるサブビューなんかを構築しとくと
強力なパフォーマンスを発揮する
なんかも親切に書いてくれてるね🌱
さてと、次はみんな大好きシミュレーター
Xcodeはシミュレーター機能が充実してる
ので、正直、オイラは9年くらい前に買った、すでにiOS17にアップグレードできなくなってるiPhone8Plusしか自分のスマホは持っていないんだけど、
iOSアプリ開発に困ったことがない
くらい🕺な強力な機能なのでじっくりレッツゴ!
ここも冒頭のサイトから図を流用すると、、、
名前としては、
A:停止ボタン
B:実行ボタン
C:デバイス選択メニュー
D:Xcodeツールバー
って感じみたいだね。それに説明を付けると
A:停止ボタン = 実行中のシミュレーターを停止
B:実行ボタン = 作ったアプリをシミュレーターで実行
C:デバイス選択メニュー = シミュレーターで実行したい機種なんかを選択
D:Xcodeツールバー = Xcodeの状態を表示
って感じかな🧐
作ったアプリで、シミュレーターにしろ実機しろ
FaceID
なんかでライブプレビューでは確認できない機能を確認するときにも使える的な感じで書いてんだけど、オイラなら、これまでの記事でゆーてるとおり、
頭の中だけでコードを書いて動かすのではなく、どんな簡単なものでもシミュレーターで作った直後に動かして、想定どおりに動いてるかを確認してるね=インクリメンタル型な構築方法
👉想定の中だけで確認して動かさないなんて、ゴミコードになっていたら、リリース前に大変😱
からね。せっかく簡単に、便利に、すぐに確認できる機能が充実してるのに、使わないなんて
愚か者としか言いようがないでしょ。
消化器置いてる家なのに、火事になった瞬間に火事になってないと言い張って、消化器を使わずに全焼させてるようなもの
「鍵を落とした場所が暗いからって
明るいところで鍵を探し続けるバカはいない」
そこにない機種でさらに確認が必要なら、
を参考に〜〜〜
で、実際、実行するといつも記事公開後でやってる
実機でやる場合
AppleIDの登録されたデバイスじゃないと実行できない的なことを書いてるので注意してね〜〜〜〜👀💦
実機とシミュレーターの設定画面
ネットワークテストも有効化できたり、
Take Screenshotsでスクショを撮る
Open Recent Logsでログを確認する
Open Consoleでコンソールフォルダを表示
なんてことも出来るみたいね👀💦
かなり機能が充実してるし、使いこなせたらかなり便利💦
ここでポイント9:シミュレーター実行中に使える機能
ここでポイント10:ビューの階層をチェック
さらに、実行中にビューの階層構造を確認することもできる。ここはちょっと、これまでの記事で作った、コードテンプレートで実行してみるけど〜〜〜
ちなみに本文には載ってないけど、
以上。
まとめ
すっげ〜〜〜色んな機能が出てきたから、Xcodeが難しそうってイメージかもしれないけど、
コードを書いたり後リビュートインスペクターなんかでビューを作る
デバッグする
シミュレーターなんかで検証する
って一連の各作業でそれぞれ使える機能をここで一気にまとめてるだけだし、できることから使っていけばオイオイ嫌でも身に付く機能。どころか使いこなせると
便利な機能ばかり
なんで、
ビビらずに色々自分の手で動かしてみてね〜〜〜
知得:知る=知る
習得:動かして好きになる=理解する
体得:動かすのが普通になる=身につける
って感じで自分の手でコードを書いたり、書いたコードを動かしたりしていかないと最初のうちは、身についたことにならないからね〜〜〜
どんな情報も触れただけでは知っただけで、理解したことにすらならない
最終的に、
自分の作りたいアプリがゼロからひとりで作れるようになればいいだけ
だし、いくらこんな記事だけを読んだだけで、全部わかった、理解した気になって、簡単そうってイメージを勝手に抱いて、
SwiftUIなんて簡単だ!誰でも出来る
なんて周囲に豪語しておきながら、いざ自分でゼロから作ろうとしても
どうしていいかわからない、ゼロから一人で簡単そうなアプリも作れない🥺
なんて恥ずかしいだけだからね〜〜〜
COBOLとかC、Java、WEBくらいで止まってるレガシーエンジニアの巣窟みたいな会社(結構な巨大企業)なんかで、実際、
「(鼻で笑いながら)SwiftとかKotlinみたいな言語とかRPAなんか簡単でしょ。そんな言語ができるくらいでプログラマとかエンジニア名乗っちゃダメ」
とか言いながら、いざ自分たちで作ってるとか公開してるアプリが、
納期を何ヶ月も遅れてリリースしたのに、潜在バグでバグりまくって誰も使わない
機能どころかポータル画面のレイアウト自体がわかりにくく、使いにくすぎて炎上の嵐
なんて星の数ほどあるからね。
あれ?簡単なんじゃなかったっけ🧐?
って感じでね。ま、そんな恥ずかしいことにならないように、
頭だけで理解した気にならず、どんな簡単だと頭では思えることも
最初のうちは、実際に手で動かしながら、体に馴染ませていってね〜〜〜
今回のまとめコード
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
.font(.title)
Text(/*@START_MENU_TOKEN@*/"おはこんばんちは、アラレちゃん"/*@END_MENU_TOKEN@*/)
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.red)
}
.padding()
}
}
#Preview{
SubView()
}
Apple公式
さてと、次回は
階層構造の確認機能も今回出てきたし、SwiftUI構築の理解に必要な
第18章 SwiftUIアーキテクチャ
をやってく〜🕺
今回でついに
これからXcodeのみの操作でよくなるから、ペースもさらに上がるはず💦
記事公開後、
でやったやり方でビューを今回も追加🕺
今回のコード
//フレームワーク
import SwiftUI
import WebKit
//ビュー管理構造体
struct ListiOSApp17DevelopmentEssentials: Identifiable {
var id: Int
var title: String
var view: ViewEnumiOSApp17DevelopmentEssentials
}
//遷移先の画面を格納する列挙型
enum ViewEnumiOSApp17DevelopmentEssentials {
case Ch1
//じっくり13で追加
case Ch2
//じっくり14で追加
case Ch3
//じっくり15で追加
case Ch4
//じっくり16で追加
case Ch5
//じっくり17で追加
case Ch6
//じっくり18で追加
case Ch7
//じっくり19で追加
case Ch8
//じっくり20、21で追加
case Ch9
//じっくり22、23で追加
case Ch10
//じっくり24で追加
case Ch11
//じっくり25で追加
case Ch12
//じっくり26で追加
case Ch13
//じっくり27,28で追加
case Ch14
//じっくり29で追加
case Ch15
//じっくり31で追加
case Ch16
//じっくり32で追加
case Ch17
}
//各項目に表示する文字列
let dataiOSApp17DevelopmentEssentials: [ListiOSApp17DevelopmentEssentials] = [
ListiOSApp17DevelopmentEssentials(id: 1, title: essentialsChapter1Title, view: .Ch1),
//じっくり13で追加
ListiOSApp17DevelopmentEssentials(id: 2, title: essentialsChapter2Title, view: .Ch2),
//じっくり13で追加
ListiOSApp17DevelopmentEssentials(id: 3, title: essentialsChapter3Title, view: .Ch3),
//じっくり15で追加
ListiOSApp17DevelopmentEssentials(id: 4, title: essentialsChapter4Title, view: .Ch4),
//じっくり16で追加
ListiOSApp17DevelopmentEssentials(id: 5, title: essentialsChapter5Title, view: .Ch5),
//じっくり17で追加
ListiOSApp17DevelopmentEssentials(id: 6, title: essentialsChapter6Title, view: .Ch6),
//じっくり18で追加
ListiOSApp17DevelopmentEssentials(id: 7, title: essentialsChapter7Title, view: .Ch7),
//じっくり19で追加
ListiOSApp17DevelopmentEssentials(id: 8, title: essentialsChapter8Title, view: .Ch8),
//じっくり20、21で追加
ListiOSApp17DevelopmentEssentials(id: 9, title: essentialsChapter9Title, view: .Ch9),
//じっくり22、23で追加
ListiOSApp17DevelopmentEssentials(id: 10, title: essentialsChapter10Title, view: .Ch10),
//じっくり24で追加
ListiOSApp17DevelopmentEssentials(id: 11, title: essentialsChapter11Title, view: .Ch11),
//じっくり25で追加
ListiOSApp17DevelopmentEssentials(id: 12, title: essentialsChapter12Title, view: .Ch12),
//じっくり26で追加
ListiOSApp17DevelopmentEssentials(id: 13, title: essentialsChapter13Title, view: .Ch13),
//じっくり27,28で追加
ListiOSApp17DevelopmentEssentials(id: 14, title: essentialsChapter14Title, view: .Ch14),
//じっくり29で追加
ListiOSApp17DevelopmentEssentials(id: 15, title: essentialsChapter15Title, view: .Ch15),
//じっくり31で追加
ListiOSApp17DevelopmentEssentials(id: 16, title: essentialsChapter16Title, view: .Ch16),
//じっくり32で追加
ListiOSApp17DevelopmentEssentials(id: 17, title: essentialsChapter17Title, view: .Ch17),
]
struct iOSApp17DevelopmentEssentials: View {
var body: some View {
VStack {
Divider()
List (dataiOSApp17DevelopmentEssentials) { data in
self.containedViewiOSApp17DevelopmentEssentials(dataiOSApp17DevelopmentEssentials: data)
}
.edgesIgnoringSafeArea([.bottom])
}
.navigationTitle("iOS開発の章目次")
.navigationBarTitleDisplayMode(.inline)
}
//タップ後に遷移先へ遷移させる関数
func containedViewiOSApp17DevelopmentEssentials(dataiOSApp17DevelopmentEssentials: ListiOSApp17DevelopmentEssentials) -> AnyView {
switch dataiOSApp17DevelopmentEssentials.view {
case .Ch1:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh1()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり13で追加
case .Ch2:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh2()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり13で追加
case .Ch3:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh3()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり15で追加
case .Ch4:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh4()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり16で追加
case .Ch5:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh5()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり17で追加
case .Ch6:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh6()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり18で追加
case .Ch7:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh7()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり19で追加
case .Ch8:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh8()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり20、21で追加
case .Ch9:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh9()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり22、23で追加
case .Ch10:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh10()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり24で追加
case .Ch11:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh11()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり25で追加
case .Ch12:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh12()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり26で追加
case .Ch13:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh13()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり27,28で追加
case .Ch14:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh14()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり29で追加
case .Ch15:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh15()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり31で追加
case .Ch16:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh16()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
//じっくり32で追加
case .Ch17:
return AnyView(NavigationLink (destination: iOSApp17DevelopmentEssentialsCh17()) {
Text(dataiOSApp17DevelopmentEssentials.title)
})
}
}
}
#Preview {
iOSApp17DevelopmentEssentials()
}
import SwiftUI
import WebKit
//iOSApp17DevelopmentEssentialsCh17.swift
//ビュー管理構造体
struct ListiOSApp17DevelopmentEssentialsCh17: Identifiable {
var id: Int
var title: String
var view: ViewEnumiOSApp17DevelopmentEssentialsCh17
}
//遷移先の画面を格納する列挙型
enum ViewEnumiOSApp17DevelopmentEssentialsCh17 {
case Sec1
}
//各項目に表示するリスト項目
let dataiOSApp17DevelopmentEssentialsCh17: [ListiOSApp17DevelopmentEssentialsCh17] = [
ListiOSApp17DevelopmentEssentialsCh17(id: 1, title: essentialsChapter17SubTitle, view: .Sec1)
]
struct iOSApp17DevelopmentEssentialsCh17: View {
var body: some View {
VStack {
Divider()
List (dataiOSApp17DevelopmentEssentialsCh17) { data in
self.containedViewiOSApp17DevelopmentEssentialsCh17(dataiOSApp17DevelopmentEssentialsCh17: data)
}
.edgesIgnoringSafeArea([.bottom])
}
.navigationTitle(essentialsChapter17NavigationTitle)
.navigationBarTitleDisplayMode(.inline)
}
//タップ後に遷移先へ遷移させる関数
func containedViewiOSApp17DevelopmentEssentialsCh17(dataiOSApp17DevelopmentEssentialsCh17: ListiOSApp17DevelopmentEssentialsCh17) -> AnyView {
switch dataiOSApp17DevelopmentEssentialsCh17.view {
case .Sec1:
return AnyView(NavigationLink (destination: Essentials17()) {
Text(dataiOSApp17DevelopmentEssentialsCh17.title)
})
}
}
}
#Preview {
iOSApp17DevelopmentEssentialsCh17()
}
//Essentials17.swift
struct Essentials17: View {
var body: some View {
VStack{
TabView {
Essentials17Code()
.tabItem {
Image(systemName: codeImageTab)
Text(codeTextTab)
}
Essentials17Points()
.tabItem {
Image(systemName: pointImageTab)
Text(pointTextTab)
}
Essentials17WEB()
.tabItem {
Image(systemName: webImageTab)
Text(webTextTab)
}
}
}
}
}
#Preview {
Essentials17()
}
struct Essentials17Code: View {
var body: some View {
ScrollView{
Text(codeEssentials17)
}
}
}
#Preview {
Essentials17Code()
}
struct Essentials17Points: View {
var body: some View {
ScrollView{
Text(pointEssentials17)
}
}
}
#Preview {
Essentials17Points()
}
struct Essentials17WebView: UIViewRepresentable {
let searchURL: URL
func makeUIView(context: Context) -> WKWebView {
let view = WKWebView()
let request = URLRequest(url: searchURL)
view.load(request)
return view
}
func updateUIView(_ uiView: WKWebView, context: Context) {
}
}
struct Essentials17WEB: View {
private var url:URL = URL(string: urlEssentials17)!
var body: some View {
Essentials17WebView(searchURL: url)
}
}
#Preview {
Essentials17WEB()
}
//タイトル
let essentialsChapter17NavigationTitle = "第17章"
let essentialsChapter17Title = "第17章 SwiftUI モードでのXcode15の使用"
let essentialsChapter17SubTitle = "第1節 SwiftUIモードでのXcode15の使用"
//コード
let codeEssentials17 = """
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}
struct SubView: View {
var body: some View{
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("こんにちは、SwiftUI🥺")
.font(.title)
Text(/*@START_MENU_TOKEN@*/"おはこんばんちは、アラレちゃん"/*@END_MENU_TOKEN@*/)
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.red)
}
.padding()
}
}
#Preview{
SubView()
}
"""
//ポイント
let pointEssentials17 = """
1 マルチプラットフォーム=複合的に対応した開発環境なので
・iOS
・WatchOS
・MacOS
・tvOS
にも対応してる。
しかも、最小限のコードの変更で、
最初はiOSなんかで作ったプロジェクトを別のOSに簡単に変更できる
2 画面の構成としては、
・A:プロジェクトナビゲーター = プロジェクト内のファイルを管理
・B:コードエディター = 実際に組み込む作業をする
・C:プレビューキャンパス = シミュレータや実機を使わずに動作検証できる
・D:アトリビュートインスペクター = 色やサイズ各状態などをコードを打たずに編集できる
・E:コンソールエリア = 実行時にPrintなんかで処理を見れる
3 各エリアは自分で使いやすいようにカスタマイズ可能
4 Canvasの構成
・A:キャンバスエリア = 現在のビューを表示する
・B:サイズボタン = 表示の拡大や縮小、100%なんかにする
・C:ピンボタン = 同じファイルに複数のプレビューなんかが
・D:プレビューツールバー = プレビューの詳細機能切り替え
さらに詳細機能としては、
・A:ライブモード = シミュレーターとか実機を使わずに実際の動きを確認
・B:選択モード = ライブではなくあくまでもビュー単体で確認
・C:バリアントボタン = 色合いとか文字サイズなんかを切り替え
・D:ローテートボタン = 縦向きや横向きなどを切り替え
・E:デバイス切り替え = iPhoneやiPadなんかの各機種を選択する
5 経験談:
⒈AutoLayoutって概念を考えなくてよくなった
⒉ライブビューでやってるのに、想定してる動きにならない
👉自分の組み方が何かおかしいんだろうか?
って考えて、コードと睨めっこしてうんうん唸るより先に、シミュレーターや実機で動かしてみてね。
6 SwiftUIで作業するってことは、
・ビュー追加
・モディファイアを使ったロジックを追加
・双方向性な宣言と他のデータインスタンスへの結びつけ
👉コードエディターの中でモディファイアと構築でやっていける
7 モディファイアとは?いい感じにする!ってイメージ
8 詳細を確認したいときは、Jump to Definitionを使う
9シミュレーター
・A:停止ボタン = 実行中のシミュレーターを停止
・B:実行ボタン = 作ったアプリをシミュレーターで実行
・C:デバイス選択メニュー = シミュレーターで実行したい機種なんかを選択
・D:Xcodeツールバー = Xcodeの状態を表示
でシミュレーター実行中に使える機能も沢山ある。
10 シミュレーター実行中に階層構造も確認できる機能もある
"""
//URL
let urlEssentials17 = "https://note.com/m_kakudo/n/n4147d790c501"
以
この記事が気に入ったらサポートをしてみませんか?