SwiftUIチュートリアルの日本語版がなかったので作ってみた

# 前提
[SwiftUiの公式チュートリアル](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)が英語版しかなく、ブラウザの翻訳機能を使っても解読が困難だったため作成。
(あと公式サイトのチュートリアルがわかりづらい)

そこそこ長い内容になってますのでご注意くださいm(_ _)m

# 注意事項
エンジニア初心者のため書き場違いが起こるかもしれません。
それでもいいよって方のみ読み進めてください。

# 環境
- OSバージョン : Ventura 13.0.1
- Xcode : 14.2

# 手順

## セクション1 : プロジェクトを作成してUIを変更してみる
### 手順1
Xcodeを開き、[**Create a new Xcode project**]を押下して新規プロジェクトを作成する

![スクリーンショット 2024-01-17 19.52.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/4235ab05-c99d-3c6f-a909-d93bad5e0adf.png)

  
### 手順2
[**iOS**]タブのApplication欄[**App**]を選択して[**Next**]を押す
![スクリーンショット 2024-01-17 20.01.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/826bed36-47e9-2b27-b2cc-0f0ac6a2b419.png)

### 手順3
プロジェクト名を入力して、[**Next**]ボタンを押下する
　その後、プロジェクトを好きな場所に保存する
![スクリーンショット 2024-01-17 20.05.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/9eeac1bb-42d4-b7bf-0757-602d4d9fbdaf.png)
プロジェクト保存後は以下のようになっていた。
　
![スクリーンショット 2024-01-17 20.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/8547d76c-13a3-2ca3-f980-e36232a5b77e.png)

画面右のiPhoneの画面が表示されていない場合は[**Editor**]の[**Canbas**]を押すことで表示されるようになる。
![スクリーンショット 2024-01-17 20.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/5d4e8299-df34-4f86-aeb5-9f5098736230.png)

### 手順4
画面左のプロジェクトナビゲータ(プロジェクトエクスプローラ)から[**LandmarksApp**]を開く
![スクリーンショット 2024-01-17 20.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/3eeaab92-486c-a2e3-bca9-97c95221b48a.png)


```swift:LandmarksApp.swift
import SwiftUI

@main
struct LandmarksApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```
- `body`プロパティは画面に表示するための1個以上のシーン※1 を返す。
- @main 属性が付与されているとそこがアプリのエントリーポイントになる。
※1 : 画面のこと


### 手順5
プロジェクトナビゲータから[**ContentView**]を開く
　
![スクリーンショット 2024-01-17 20.24.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/1434eed5-435d-6fa7-afee-08f91d50da16.png)
画面右にiPhoneの画面が表示されており、表示されている内容のソースが画面に表示されている。

### 手順6
`VStack{}`ブロックを削除して、新たに`Text("Hello SwiftUI!")`を記述する
　コードを変更するとiPhoneの画面が変わり、**Hello SwiftUI!**が表示される
![スクリーンショット 2024-01-17 20.43.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/a1eb7a04-7c1f-fcbe-7e63-7516eb8655e7.png)

## セクション2 : コードを変更したりインスペクタを使ってビューの表示を変更してみる。

### 手順1
プレビュー画面左下のマウスカーソルボタンを押してSelectableモードにする。
　Selectable状態になるとインスペクタが利用可能になる。
 ![スクリーンショット 2024-01-17 20.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/cb8c190d-91b9-01a5-36db-0b9ddf3e9f22.png)

### 手順2
プレビュー画面の`Hello SwiftUI!`を `command + クリック` する
　　ポップアップが表示されるので、[**Show SwiftUI Inspector...**]を押す。
  ![スクリーンショット 2024-01-17 21.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/7046dba9-aef3-ad4c-5d4f-3acba881ef7e.png)
  
  - 表示されたポップアップから**Text**を`Turtle Rock`に変更
  - Fontを`Inherited`から`Title`に変更する
  - Colorを`Green`に変更する
  (左側のコードも変更されます)

![スクリーンショット 2024-01-17 21.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/055e6e2c-15b7-1b97-f210-41607f5ce50d.png)

### 手順3
プレビュー画面左下の再生？ボタンを押してLiveモードに戻しておく
![スクリーンショット 2024-01-17 21.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/c316b027-9298-bc45-c2bb-e494209f79a4.png)

## セクション3 : タイトル以外の情報を追加してみる
### 手順1
ContentViewファイルの`Text("Turtle Rock")`となっている箇所を`cmd + クリック`をし、ポップアップから[Embed in VStack]を押す。

以下のようにTextブロックが`VStack`で囲われるはず
```swift:ContentView.swift
// ~~省略~~
var body: some View {
    VStack {
        Text("Turtle Rock")
            .font(.title)
            .foregroundColor(Color.green)
        .padding()
    }
}
// ~~省略~~
```

### 手順2
XCode右上の[+]ボタンを押下し、表示されたウィンドウから**Text**を選択する.
 選択した**Text**を元あるTextブロックの真下に配置する。
![スクリーンショット 2024-01-31 7.51.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/95f63146-6722-73e9-67a2-736c2677ae7d.png)
![スクリーンショット 2024-01-31 7.52.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/3c6c8a9b-a84d-fda0-fa45-ccd773af03b4.png)


 以下のように新たにTextが挿入される
 ```swift:ContentView.swift
 // ~~省略~~
 var body: some View {
    VStack {
        Text("Turtle Rock")
            .font(.title)
            .foregroundColor(Color.green)
        Text("Placeholder")
    }
}
// ~~省略~~
 ```

### 手順3
追加したTextの内容を変更して、フォントのスタイルを`.subheadline(小見出し)`に設定する。
 ```swift:ContentView.swift
 var body: some View {
    VStack {
        Text("Turtle Rock")
            .font(.title)
            .foregroundColor(Color.green)
        Text("Joshua Tree National Park")
            .font(.subheadline)
    }
}
 ```

 追加後はタイトルの下に小見出し行が追加されている。
 ![スクリーンショット 2024-01-31 8.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/3a689105-fa9a-81fb-a2fb-45e6820c0f6c.png)

### 手順4
先ほど追加したVStackを`VStack(alignment: .leading)`に変更し、左寄せにする
 ![スクリーンショット 2024-01-31 8.25.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/f8a38d81-be27-2a35-0812-54a04247086d.png)

```swift:ContentView.swift
var body: some View {
    VStack(alignment: .leading){
        Text("Turtle Rock")
            .font(.title)
            .foregroundColor(Color.green)
        Text("Joshua Tree National Park")
            .font(.subheadline)
    }
}
```

### 手順5
3の手順で追加したTextブロックを`HStack`ブロックで囲って、`Text`を追加する

```swift:ContentView.swift
var body: some View {
    VStack(alignment: .leading) {
        Text("Turtle Rock")
            .font(.title)
        HStack {   // 追加
            Text("Joshua Tree National Park")
                .font(.subheadline)
            Text("California") // 追加
                .font(.subheadline)
        }
    }
}
```
[変更後画面]
![スクリーンショット 2024-02-01 13.52.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/6862fd56-9fa5-0166-545c-854815f4317e.png)


### 手順6
`Spacer()`を追加して画面幅いっぱいに文字列を表示し、`padding()`を追加して余白をつける
```swift:ContentView.swift
var body: some View {
    VStack(alignment: .leading) {
        Text("Turtle Rock")
            .font(.title)
        HStack {
            Text("Joshua Tree National Park")
                .font(.subheadline)
            Spacer() // 追加
            Text("California")
                .font(.subheadline)
        }
    }
    .padding()

}
```
[変更後画面]
![スクリーンショット 2024-02-01 13.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/71dc6f0f-47f6-17af-48fd-31d53892a117.png)

## セクション4 画面に画像を追加する

### 手順1
SwiftUIのチュートリアルページからダウンロードしたプロジェクトファイルの`turtlerock@2x.jpg`をAssetsにドラッグ&ドロップする。

![スクリーンショット 2024-02-01 14.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/89e67545-75a6-c996-945e-76b57a6ee9b4.png)


※画像をダウンロードしていない方は以下の画像を保存して利用してください。
[](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)
![turtlerock@2x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/7a19544f-d103-3f61-845c-7d88d7f67a51.jpeg)

### 手順2
[File > New > SwiftUI View] を選択し、`CircleImage.swift`としてファイルを作成する。
![スクリーンショット 2024-02-01 14.15.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/bbfab931-9ee5-e586-36d7-93272b7610c2.png)

### 手順3
作成したファイルのコードを変更し、先ほど`Asetts`に追加した画像を表示させる。
```swift:CircleImage.swift
struct CircleImage: View {
    var body: some View {
        Image("turtlerock") // 変更
    }
}
```
個人で用意した画像を利用している方は、`Image()`の引数に先ほど`Assets`に追加した際の名称を記載する。
![スクリーンショット 2024-02-01 14.23.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/b8fe9b45-3863-ea32-945d-e759315b343e.png)

[変更後画面]
![スクリーンショット 2024-02-01 14.25.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/f6d8e662-362b-27f3-0618-b33bf38bd3ea.png)

### 手順3
コードを追加し、画像を丸く切り取る。

```swift:CircleImage
struct CircleImage: View {
    var body: some View {
        Image("turtlerock")
            .clipShape(Circle()) // 追加
    }
}
```
[変更後画面]
![スクリーンショット 2024-02-01 14.28.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/265aba18-5182-1f7f-f0c4-bd14b54cef6b.png)

※もし個人で用意した画像を利用していて、サイズが表示サイズがおかしくなっている場合は以下のようにすることで同じ状態になるはず。
```swift
struct CircleImage: View {
    var body: some View {
        Image("original_image")
            .resizable()    // 追加
            .scaledToFit()  // 追加
            .clipShape(Circle())
    }
}
```

### 手順4
丸くした画像にスタイルの設定をする。

```swift:CircleImage.swift
var body: some View {
    Image("turtlerock")
        .clipShape(Circle())
        .overlay {                                 // 追加 
            Circle().stroke(.white, lineWidth: 4)  // 追加  外枠を追加
        }                                          // 追加      
        .shadow(radius: 7)                         // 追加  影を追加
}
```

[変更後画面]
![スクリーンショット 2024-02-01 14.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/85046823-df9f-66e4-33eb-a3b744af87c1.png)


## セクション5 他のフレームワーク(MapKit)を利用する。

### 手順1
新たにファイルを作成する。
ファイル名は`MapView.swift`とする。
手順については、[セクション4の手順２を参照](#手順2-3)

### 手順2
`MapKit`をimportし、利用可能な状態にする。

```swift:MapView.swift
import SwiftUI
import MapKit // 追加

struct MapView: View {
// ~~省略~~

```

### 手順3
マップの初期位置を設定し、画面に表示する。
(私の環境ではここだけうまくいかず、独自で解決してみたためうまくいかない方は[公式のSection5 step3](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)を試してみてください)

```swift:MapView.swift
struct MapView: View {
    var body: some View {
        Map(coordinateRegion: .constant(region))
    }
}

// ここから下を追加
private var region: MKCoordinateRegion {
    MKCoordinateRegion(
        center: CLLocationCoordinate2D(
            latitude: 34.011_286, longitude: -116.166_868),
            span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
    )
}
```

[解説]
- `MKCoordinateRegion` ...地図の表示領域を定義するクラス。
- `CLLocationCoordinate2D`...中心座標を緯度経度を指定して定義してます。
- `MKCoordinateSpan`...表示する範囲を指定してます。

### 手順4
先ほど定義した地図の情報を用いて画面に表示する。
(ここも私の環境ではうまくいかなかったので、うまくいかない方は[公式のSeciton5 step4](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)を試してください

```swift:MapView
struct MapView: View {
    var body: some View {
        Map(coordinateRegion: .constant(region)) // 変更
    }
}
```
うまくいくと以下のようになります。

[変更後画面]
![スクリーンショット 2024-02-01 15.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/06c00755-b46d-0e4c-1dea-93ac68d9e2fc.png)


## セクション6 これまで作ったコンポーネントを合体させる

### 手順1
少し前まで作成していた`ContentView.swift`を開く

### 手順2
`VStack`ブロックを追加する。
```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{  // 追加
            VStack(alignment: .leading){
                Text("Turtle Rock")
                    .font(.title)
                    .foregroundColor(Color.green)
                HStack{
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }    // 追加
    }
}
```

### 手順3
先ほど作成したMapViewを利用する。
```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{
            MapView() // 追加
                .frame(height: 300) // 追加
            VStack(alignment: .leading){
                Text("Turtle Rock")
                    .font(.title)
                    .foregroundColor(Color.green)
                HStack{
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }
    }
}
```

[追加後画面]
![スクリーンショット 2024-02-01 15.19.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/6bf655ac-9948-06df-da9e-979529f397d9.png)

### 手順4
次にイメージ画像を追加する。

```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{
            MapView()
                .frame(height: 300)
            
            CircleImage()
            
            VStack(alignment: .leading){
                Text("Turtle Rock")
                    .font(.title)
                    .foregroundColor(Color.green)
                HStack{
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }
    }
}
```

[追加後画面]
![スクリーンショット 2024-02-01 15.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/a74ef2b8-7c23-9089-bfc3-659af7963090.png)

### 手順5
スタイルを追加し、レイアウトを調整する。

```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{
            MapView()
                .frame(height: 300)
            
            CircleImage()
                .offset(y: -130)        // 追加
                .padding(.bottom, -130) // 追加
            
//     ~~ 省略 ~~
}
```

[追加後画面]
![スクリーンショット 2024-02-01 15.24.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/720c1a74-f60b-6d4a-8e39-dff4e1f8bfe0.png)

### 手順6
画面下に説明を記載する余白を作成する。

```swift:ContentView.swift
// ~~ 省略 ~~
        }
    }
    .padding()
    
    Spacer() // 追加
}
```

[追加後画面]
追加すると画面下あたりに空白が生まれる。
![スクリーンショット 2024-02-01 15.26.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/40c30e6e-2133-467f-3dd0-071e4095293e.png)

### 手順7
先ほど作成した余白に説明を記載する。

```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{
            MapView()
                .frame(height: 300)
            
            CircleImage()
                .offset(y: -130)
                .padding(.bottom, -130)
            
            VStack(alignment: .leading){
                Text("Turtle Rock")
                    .font(.title)
                    .foregroundColor(Color.green)
                HStack{
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
                
                Divider() // 追加 (区切り線を引く)
                
                Text("About Turtle Rock")           // 追加
                    .font(.title2)                  // 追加    
                Text("Descriptive text goes here.") // 追加
            }
            .padding()
            
            Spacer()
        }
    }
}
```
[追加後画面]
![スクリーンショット 2024-02-01 15.30.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/200afa79-6749-2035-49a8-3225bcae764e.png)


### 手順8
`HStack`内のTextに直接付与していたスタイルを`HStack`自体に付与する。
```swift:ContentView.swift
struct ContentView: View {
    var body: some View {
        VStack{
            MapView()
                .frame(height: 300)
            
            CircleImage()
                .offset(y: -130)
                .padding(.bottom, -130)
            
            VStack(alignment: .leading){
                Text("Turtle Rock")
                    .font(.title)
                    .foregroundColor(Color.green)
                HStack{
                    Text("Joshua Tree National Park")
                        .font(.subheadline)   // 削除する
                    Spacer()
                    Text("California")
                        .foregroundStyle(.secondary)  // 削除する
                }
                .font(.subheadline)          // 追加
                .foregroundStyle(.secondary) // 追加
                
                Divider()
                
                Text("About Turtle Rock")
                    .font(.title2)
                Text("Descriptive text goes here.")
            }
            .padding()
            
            Spacer()
        }
    }
}
```

[!!!!!!完成!!!!!!!]
![スクリーンショット 2024-02-01 15.33.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677920/8d667aac-67b8-62cc-865a-e01977598310.png)

ここまでがチュートリアルに記載されている内容になっております。


# さいごに
長い記事でしたが読んでいただきありがとうございました。
今後趣味で何か作ってみたいですね