SwiftUIチュートリアルのポイントまとめ① Viewの制作・統合

この記事SwiftUIのためのいくつか用意されている公式チュートリアルのうち、【SwiftUI Essentials】Creating and Combining Viewsの内容を自分なりにまとめたものになります。

注) プロジェクトの作成

プロジェクトを作成する際は、下画像のように「User Interface」の項目をSwiftUIにしておくことを忘れないようにしましょう。

このような感じになっていればおk。

import SwiftUI  

struct ContentView: View {  
    var body: some View {  
        Text("Hello, World!")  
    }  
}  

//ContentView_Previewsはプレビュー用のコードなので今後弄る必要はない  
struct ContentView_Previews: PreviewProvider {  
    static var previews: some View {  
        ContentView()  
    }  
}  

該当のチュートリアルを進めいていく上でポイントと思った箇所は次の3つです。

ポイント

  1. SwiftUIパーツの加工
  2. Stackでパーツをまとめる
  3. UIKitとSwiftUIを共存させる

順次詳しく解説していきます

ポイント1. SwiftUIパーツの加工

下画像のようにHello Worldを加工してみる。ここで加工しているTextに加えてImageView等も同様のやり方で加工が可能なので割愛。

この方法は次の二通りある

  1. コードから変更を加える方法
  2. GUIから変更を加える方法

1. コードから変更を加える方法
直接コードを書く方法が一つ

import SwiftUI  

struct ContentView: View {  
    var body: some View {  
        Text("Hello, World!")  
            .foregroundColor(.blue) //ココ  
            .font(.largeTitle)  //ココ  
    }  
}  

2. GUIから変更を加える方法
加工したいパーツを⌘クリック→「Show SwiftUI Inspecter」と開くことで各プロパティをいじることができる。GUI上で設定すると対応するコードが自動的に記入される

ポイント2. Stackでパーツをまとめる

三つのTextをStackでまとめています。

注目すべきポイントは次の三つでしょうか。

  • VStackには左揃えのAlignment、.leadingを設定している
  • Spacer()で「ヤッホ」と「あああ」の間隔を作っている
  • padding()で枠からの間隔を作っている
import SwiftUI  

struct ContentView: View {  
    var body: some View {  
        VStack(alignment: .leading) {  //ココ  
            Text("Hello, World!")  
                .font(.largeTitle)  
                .foregroundColor(.blue)  
            HStack {  
                Text("ヤッホ")  
                    .font(.subheadline)  
                Spacer()  //ココ  
                Text("あああ")  
                    .font(.subheadline)  
            }  
        }  
    .padding()  //ココ  
    }  
}  

ポイント3. UIViewRepresentableでSwiftUIを統合する

protocol UIViewRepresentable where Self.Body == Never  

このプロトコルをViewに継承させることでSwiftUIの画面を統合することができます!!

手順1. Viewの制作

makeUIView()というメソッドでViewを生成するようです。今回はMapViewを返して欲しいので、

import SwiftUI  
import MapKit  

struct MapView: UIViewRepresentable {  
    //UIKitViewの描画を行う  
    func makeUIView(context: Context) -> MKMapView {  
        MKMapView(frame: .zero)  
    }  

    //更新されたときの挙動  
    func updateUIView(_ uiView: MKMapView, context: Context) {  
        let coordinate = CLLocationCoordinate2D(  
            latitude: 34.011286, longitude: -116.166868)  
        let span = MKCoordinateSpan(latitudeDelta: 2.0, longitudeDelta: 2.0)  
        let region = MKCoordinateRegion(center: coordinate, span: span)  
        uiView.setRegion(region, animated: true)  
    }  
}  

手順2 制作したViewをStack内に埋め込む

手順1で作成したMapView()を加えます。特にVSStackでまとめていることに注意する

struct ContentView: View {  
    var body: some View {  
        VStack {  
            MapView()  
                .edgesIgnoringSafeArea(.top)  
                .frame(height: 300)  

            VStack(alignment: .leading) {  
                Text("Hello, World!")  
                    .font(.largeTitle)  
                    .foregroundColor(.blue)  
                HStack {  
                    Text("ヤッホ")  
                        .font(.subheadline)  
                    Spacer()   
                    Text("あああ")  
                        .font(.subheadline)  
                }  
            }  
            .padding()  
            Spacer()  
        }  
    }  
}  

まとめ

  • パーツはStackでまとめられ、.paddingSpacer()で位置の調整を行うことができる
  • 各パーツはコード及びGUIからも簡単にプロパティの設定を行うことができて便利
  • UIViewRepresentableを継承したViewはSwiftUIに統合が可能