📱

iOSアプリ開発 - 2.SwiftUI

2021/10/14に公開

概要

SwiftUIの使い方をまとめました。

  • Swiftのバージョン : 5.5
  • Xcodeのバージョン : 13.0
# Swiftのバージョン確認
$ swift --version
swift-driver version: 1.26.9 Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
Target: x86_64-apple-macosx11.0

# Xcodeのバージョン確認
$ xcodebuild -version
Xcode 13.0
Build version 13A233

# 対話型実行環境を起動
$ swift

Welcome to Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57).
Type :help for assistance.
  1> print("Hello Swift")
Hello Swift

`control` + `D` => 停止

SwiftUIとは

SwiftUI is a modern way to declare user interfaces for any Apple platform. Create beautiful, dynamic apps faster than ever before.
https://developer.apple.com/tutorials/swiftui より引用

https://developer.apple.com/tutorials/swiftui


Stacks

HStack

コンテンツを横に並べる

HStack {
    Text("こんにちは!")
    Text("田村たいようです!")
}

VStack

コンテンツを縦に並べる

VStack {
    Text("こんにちは!")
    Text("田村たいようです!")
}

状態管理

@State

Stateとは、

  • プロパティの変更がSwiftUIによってモニタリングされ、再描画される
  • @Stateで宣言したプロパティは、View内部と子Viewからしか参照/変更できない
import SwiftUI

struct ContentView: View {
    @State private var greeting: String = "おはよう!"
    // @State private var プロパティ名: 型 = 初期値
    // 型には、基本型(String,Bool,...)とStruct型を指定可能
    
    var body: some View {
        VStack {
            GreetingText(greeting: $greeting)
	    // @Stateで宣言されたプロパティは`$`をつけて渡す
	    // 子View(引数: $プロパティ)

            Button(action: { self.changeGreeting() }) {
                Text("切り替える")
            }
        }
    }
    
    func changeGreeting() {
        if greeting == "おはよう!" {
            greeting = "こんばんは!"
        } else {
            greeting = "おはよう!"
        }
    }
}

struct GreetingText: View {
    @Binding var greeting: String
    // `@Binding` : 他のViewの@Stateで宣言されたプロパティを参照・変更する
    // @Binding var プロパティ名: 型
    
    var body: some View {
        Text(greeting)
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

@ObservedObject

@Stateにクラス型を指定しても、再描画されません。そのため、クラスの状態を監視し、再描画したい場合は@ObservedObjectでプロパティを宣言します。

import SwiftUI

struct ContentView: View {
    @ObservedObject var greeting: Greeting = Greeting()
    
    var body: some View {
        VStack {
            GreetingText(greeting: greeting)
	    // 子ビューには、インスタンスをそのまま渡せばよい

            Button(action: { self.changeGreeting() }) {
                Text("違う挨拶で!")
            }
        }
    }
    
    func changeGreeting() {
        if greeting.text == "おはよう!" {
            greeting.text = "こんばんは!"
        } else {
            greeting.text = "おはよう!"
        }
    }
}

struct GreetingText: View {
    @ObservedObject var greeting: Greeting
    
    var body: some View {
        Text("\(greeting.firstName)さん、\(greeting.text)")
            .padding()
    }
}

class Greeting: ObservableObject {
    @Published var firstName: String = "たいよう"
    @Published var text: String = "おはよう!"
    // 監視対象となるプロパティを`@Published`で宣言
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

@EnvironmentObject

アプリ全体で参照/更新する値には@EnvironmentObjectで宣言する。

アプリ名App.swift

@main
struct アプリ名App: App {    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(クラス名())
        }
    }
}

ContentView.swift

import SwiftUI

class クラス名: ObservableObject {
    @Published var プロパティ名:= 初期値
    // ...
}

struct ContentView: View {
    @EnvironmentObject var プロパティ名: クラス名
    
    var body: some View {
        // ...
    }
}

struct 別のView: View {
    @EnvironmentObject var プロパティ名: クラス名
    
    var body: some View {
        // ...
    }
}

画像表示


画像カルーセルの表示


参考文献

Discussion