SwiftUIで簡単なUIを作ってみました。
まずはXcode11で新規プロジェクトを作成します。
テンプレートは「Single View App」を選びました。
プロジェクト構成は以下のようになっています。
Xcode11からはSceneDelegate.swiftというファイルが追加されています。 これはiPadで画面に複数アプリ表示する際に使うクラスで、今までのAppDelegateの役割の一部を担っています。 今回はSwiftUIを中心に見たいので深堀りしないことにします。
まずはアプリを立ち上げてみます。 アプリを起動すると下のようにHello, World!と表示されます。
その下にラベルを1つ追加してみたいと思います。 ContentViewクラスを以下のように修正します。 2つ縦に並べるのはVStackというクラスを使っています。
struct ContentView: View { var body: some View { VStack { Text("Hello, World!") Text("Goodnight, World!") } } }
アプリを起動するとラベルが2つ表示されています。
次にラベル間を少し空けてみます。 VStackの初期化時にspacingを渡します。
struct ContentView: View { var body: some View { VStack(spacing: 200) { Text("Hello, World!") Text("Goodnight, World!") } } }
これで間隔を200pxにする事ができました。
ラベルと色やフォントも変更してみます。
struct ContentView: View { var body: some View { Text("Hello, World!").font(Font.system(size: 50)).foregroundColor(Color(red: 1, green: 1, blue: 0)) } }
少し見づらいですが黄色の大きめの文字に変わりました。
次はボタンの追加とタップ時のアクション追加を行います。
struct ContentView: View { var body: some View { Button("ボタン") { print(10) } } }
ボタンをタップするとデバッグエリアに10が表示されます。
次はボタンタップ時にアラートも表示してみます。
struct ContentView: View { @State var isPresented = false var body: some View { Button("ボタン") { self.isPresented = true }.alert(isPresented: $isPresented) { Alert(title: Text("Title"), message: Text("Message")) } } }
アラートを表示する事ができました。
この.alert(isPresented:)
はButtonに付いている必要はなく以下のようにTextに付いていても動きます。
struct ContentView: View { @State var isPresented = false var body: some View { VStack { Text("Hello, World!").alert(isPresented: $isPresented) { Alert(title: Text("Title"), message: Text("Message")) } Button("ボタン") { self.isPresented = true } } } }
次はボタンを押した時にテキストの内容を変える処理をします。
struct ContentView: View { @State var text = "Hello, World" var body: some View { VStack { Text(text) Button("ボタン") { self.text = "Goodnight, World" } } } }
ボタンを押すとテキストを変更する事ができました。
以下のようにViewModelを別途作る事もできます。
class MyViewModel : ObservableObject, Identifiable { @Published var text: String = "Hello, World" } struct ContentView: View { @ObservedObject var viewModel = MyViewModel() var body: some View { VStack { Text(viewModel.text) Button("ボタン") { self.viewModel.text = "Goodnight, World" } } } }
データをTextFieldと紐付ける事もできます。
TextFieldの引数はBinding<String>
なので$viewModel.text
とドルを付けてBindingオブジェクトに変えて上げる必要があります。
class MyViewModel : ObservableObject, Identifiable { @Published var text: String = "Hello, World" } struct ContentView: View { @ObservedObject var viewModel = MyViewModel() var body: some View { VStack { Text(viewModel.text) TextField("Placeholder", text: $viewModel.text) } } }
画面遷移はNavigationViewを使うと実現できます。
struct ContentView: View { var body: some View { NavigationView { NavigationLink(destination: DestinationView()) { Text("ボタン") } } } } struct DestinationView: View { var body: some View { Text("遷移先") } }