Develop Apps for iOSをやってみる〜その1〜

Pocket

Develop Apps for iOSをやってみる 〜その1〜

はじめに

DX推進室の野上です。
私は普段、Androidアプリの開発をしているのですが、iOSアプリもできたらいいなぁと思っていました。
何かいい教材はないものかと調べたところ、Appleが公式にトレーニングメニューを出していたのでやってみたいと思います。
長いので何回かにわけてやってみたいと思います。


Develop Apps for iOS

ここ にトレーニングページがあります。
全編英語なので、がんばって訳しながら実施していきます。


ゴール

Develop Apps for iOSのトレーニングページのSwiftUIの項目を終わらせる。


何を作るのか?

  • ここ に概要が記載されています。

スクラム開発におけるデイリーミーティングを管理するScrumdingerというアプリを作りますということが書いてあります(はず)
機能としては

  • スクラムリスト
    • アプリのメイン画面。タップすると詳細を見ることができ、+をタップすると新しいスクラムを追加することができる。
  • スクラム詳細と編集
    • デイリーミーティングの詳細と参加者の名前の一覧。ミーティングタイマーを使用してミーティング時間を記録することができる。
  • ミーティングタイマー
    • デイリーミーティングにおける報告者の発言時間を管理し、時間が来ると音を鳴らして次の報告者に順番を回す。

Stackを使ってViewを配置する

プロジェクトを作る

まずはXcodeで新しいプロジェクトを作成します。

  • Xcodeを立ち上げて「Create new Xcode project」を選択する
  • iOSのAppテンプレートを選択してNextボタンを押下する
  • Product Nameに「Scrumdinger」
  • Interfaceに「SwiftUI」
  • Life Cycleに「SwiftUI App」
  • Organization Identifierは適当に
  • Languageは「Swift」

Nextボタンを押して保存先を選択するとプロジェクトが作成されます。
このテンプレートにはRootビューとなるContentContentView.swiftと
アプリのエントリーポイントを定義するScrumdingerApp.swiftが含まれます。


タイマー画面を作成する

ContentView.swiftを開いて以下のコードを転記する。

import SwiftUI

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

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

※XcodeのPreview画面の右の「Resume」を押下するとプレビューが再作成されます

ContentView.swiftをアプリの目的に合わせた名前にリファクターします。
「ContentView」を右クリック(二本指タップ)してRefactor > Renameを選択し「MeetingView」に名前を変更します。
「ContentView_Previews」も「」に変更しておいてください。

次にプログレスバーを表示します。
TextだったところをProgressViewに置き換えます。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        ProgressView(value: 5, total: 15)
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

プログレスバーの下に経過時間と残り時間を表示します。
VStackを使ってViewを縦に、HStackを使って横にViewを並べます。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        VStack {
            ProgressView(value: 5, total: 15)
            HStack {
                Text("Seconds Elapsed")
                Text("Seconds Remaining")
            }
        }
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

経過時間と残り時間に画像付きの数値をLabelとして追加します。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        VStack {
            ProgressView(value: 5, total: 15)
            HStack {
                VStack {
                    Text("Seconds Elapsed")
                    Label("300", systemImage: "hourglass.bottomhalf.fill")
                }
                VStack {
                    Text("Seconds Remaining")
                    Label("600", systemImage: "hourglass.tophalf.fill")
                }
            }
        }
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

ここまででこんな画面が出来上がったはず。

ビューのスタイルと修飾

先ほど作ったプログレスバーなどをヘッダーにして調整します。
VStackの間にSpacer()を記述して、親Viewに対してVStackのあまりの空間を埋めます。
また経過時間と残り時間のVStackに修飾を施し、前詰めと後ろ詰めを設定します。(alignment:)
またテキストのフォントサイズをcaptionサイズに指定します。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        VStack {
            ProgressView(value: 5, total: 15)
            HStack {
                VStack(alignment: .leading) {
                    Text("Seconds Elapsed")
                        .font(.caption)
                    Label("300", systemImage: "hourglass.bottomhalf.fill")
                }
                Spacer()
                VStack(alignment: .trailing) {
                    Text("Seconds Remaining")
                        .font(.caption)
                    Label("600", systemImage: "hourglass.tophalf.fill")
                }
            }
        }
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

ヘッダーにあたる部分のスタイルが決まったので、次に画面真ん中にタイマー用のリングを仮描画します。
また、フッター部分を作成します。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        VStack {
            ProgressView(value: 5, total: 15)
            HStack {
                VStack(alignment: .leading) {
                    Text("Seconds Elapsed")
                        .font(.caption)
                    Label("300", systemImage: "hourglass.bottomhalf.fill")
                }
                Spacer()
                VStack(alignment: .trailing) {
                    Text("Seconds Remaining")
                        .font(.caption)
                    Label("600", systemImage: "hourglass.tophalf.fill")
                }
            }
            Circle()
                .strokeBorder(lineWidth: 24, antialiased: true)
            HStack {
                Text("Speaker 1 of 3")
                Spacer()
                Button(action: {}) {
                    Image(systemName: "forward.fill")
                }
            }
        }
        .padding()
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

VStackに.padding()を追加することによって、画面枠から少し内側に描画されるようになりました。
ここまでで以下のような画面ができあがります。

読み上げ用のデータの設定

アクセシビリティをあげるために、音声読み上げ用のデータを設定します。
HStackの子Viewにはアクセシビリティを付けたくないので、無視する設定を行います。
必要なViewに読み上げ用のLabelとValueテキストを設定します。

import SwiftUI

struct MeetingView: View {
    var body: some View {
        VStack {
            ProgressView(value: 5, total: 15)
            HStack {
                VStack(alignment: .leading) {
                    Text("Seconds Elapsed")
                        .font(.caption)
                    Label("300", systemImage: "hourglass.bottomhalf.fill")
                }
                Spacer()
                VStack(alignment: .trailing) {
                    Text("Seconds Remaining")
                        .font(.caption)
                    Label("600", systemImage: "hourglass.tophalf.fill")
                }
            }
            .accessibilityElement(children: .ignore)
            .accessibilityLabel(Text("Time remaining"))
            .accessibilityValue(Text("10 minutes"))
            Circle()
                .strokeBorder(lineWidth: 24, antialiased: true)
            HStack {
                Text("Speaker 1 of 3")
                Spacer()
                Button(action: {}) {
                    Image(systemName: "forward.fill")
                }
                .accessibilityLabel(Text("Next speaker"))
            }
        }
        .padding()
    }
}

struct MeetingView_Previews: PreviewProvider {
    static var previews: some View {
        MeetingView()
    }
}

ここまでのまとめ

  • HStackで横に、VStackで縦に要素を並べることができる(alignmentでいろいろ指定できる)
  • Spacer()で間を埋めることができる
  • .font()でフォントサイズを指定する
  • .padding()でパディングが指定、パディングサイズも値で指定できる
  • accessibilityXXXXでアクセシビリティの設定ができる

トレーニングページでは、最後に理解度チェックがあるのでやってみるといいでしょう。
次回はCardViewを作成します。

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です