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

Pocket

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

はじめに

DX推進室の野上です。
前回 の続きです


どこから?

だんだん長くなってきましたが、今回はここから続けます。


最初に

今回も用意されたプロジェクトファイルがあります。
011

が、前回と同じように無視します(ホントはダメ)


画面の遷移を作成する

NavigationViewを作る

NavigationView を使うことで階層的な画面遷移を実装することができます。
ルートViewをNavigationViewで囲ってみましょう。
ScrumdingerApp.swiftに修正を行います。

import SwiftUI

@main
struct ScrumdingerApp: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ScrumsView(scrums: DailyScrum.data)
            }
        }
    }
}

次に、Listの各要素をタップした際の遷移をScrumsViewに実装していきましょう。
NavigationLinkを使って画面遷移を実装できます。
仮でscrum.titleをTextで表示する遷移を実装します。
Previewの方にNavigationViewも追加しておきます。
Previewが階層構造を理解して、自動的に戻る遷移実装してくれます。

import SwiftUI

struct ScrumsView: View {
    let scrums: [DailyScrum]
    
    var body: some View {
        List {
            ForEach(scrums) { scrum in
                NavigationLink(destination: Text(scrum.title)) {
                    CardView(scrum: scrum)
                        .listRowBackground(scrum.color)
                }
            }
        }
    }
}

struct ScrumsView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ScrumsView(scrums: DailyScrum.data)
        }
    }
}

CardViewに設定されているlistRowBackgroundをNavigationLinkの方に移動させます。
(ただしプロジェクトファイルをダウンロードして使っていないと意味がないです)
navigationTitleを使って、タイトルもつけておきましょう。
また、navigationBarItemsを使って、右上に今後要素を追加する際の+ボタンを表示しておきましょう。
この時点では、タップしても空のアクションが動作するだけです。

import SwiftUI

struct ScrumsView: View {
    let scrums: [DailyScrum]
    
    var body: some View {
        List {
            ForEach(scrums) { scrum in
                NavigationLink(destination: Text(scrum.title)) {
                    CardView(scrum: scrum)
                }
                .listRowBackground(scrum.color)
            }
        }
        .navigationTitle("Daily Scrums")
        .navigationBarItems(trailing: Button(action: {}) {
            Image(systemName: "plus")
        })
    }
}

struct ScrumsView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ScrumsView(scrums: DailyScrum.data)
        }
    }
}

ここまでで画面は以下のようになっているはずです。

012

XCode上でPreviewを実行して、動作を確認してみてください。
各要素をタップすると、スクラムタイトルを表示する画面に遷移でき、元の画面に戻ることができるようになっているはずです。

Detail Viewを作る

新しくScrumの詳細を表示するViewを作成します。
DetailView.swiftを新しく作成して、以下の内容を記述します。

import SwiftUI

struct DetailView: View {
    let scrum: DailyScrum

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

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            DetailView(scrum: DailyScrum.data[0])
        }
    }
}

DetailViewの仮実装ができたので、ScrumsViewのNavigationLinkのdestinationをDetailViewに変更しましょう。

import SwiftUI

struct ScrumsView: View {
    let scrums: [DailyScrum]
    
    var body: some View {
        List {
            ForEach(scrums) { scrum in
                NavigationLink(destination: DetailView(scrum: scrum)) {
                    CardView(scrum: scrum)
                }
                .listRowBackground(scrum.color)
            }
        }
        .navigationTitle("Daily Scrums")
        .navigationBarItems(trailing: Button(action: {}) {
            Image(systemName: "plus")
        })
    }
}

struct ScrumsView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ScrumsView(scrums: DailyScrum.data)
        }
    }
}

これでListの要素をタップした際にDetailViewに遷移するようになりました。
次に、DetailViewの中身を実装していきましょう。
まずはMetting Infoから。
body部分のTextを変更して以下のようにします。

import SwiftUI

struct DetailView: View {
    let scrum: DailyScrum

    var body: some View {
        List {
            Section(header: Text("Meeting Info")) {
                Label("Start Meeting", systemImage: "timer")
                    .font(.headline)
                    .foregroundColor(.accentColor)
                    .accessibilityLabel(Text("Start meeting"))
                HStack {
                    Label("Length", systemImage: "clock")
                        .accessibilityLabel(Text("Meeting length"))
                    Spacer()
                    Text("\(scrum.lengthInMinutes) minutes")
                }
                HStack {
                    Label("Color", systemImage: "paintpalette")
                    Spacer()
                    Image(systemName: "checkmark.circle.fill")
                }
                .accessibilityElement(children: .ignore)
            }
        }
        .listStyle(InsetGroupedListStyle())
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            DetailView(scrum: DailyScrum.data[0])
        }
    }
}

ここまででDetailViewは以下のような画面になっているはずです。

013

次にMeetingの参加者を表示します。
MEETING INFOと同じようにSectionを追加して、DailyScrumのattendeesを表示しましょう。

import SwiftUI

struct DetailView: View {
    let scrum: DailyScrum

    var body: some View {
        List {
            Section(header: Text("Meeting Info")) {
                Label("Start Meeting", systemImage: "timer")
                    .font(.headline)
                    .foregroundColor(.accentColor)
                    .accessibilityLabel(Text("Start meeting"))
                HStack {
                    Label("Length", systemImage: "clock")
                        .accessibilityLabel(Text("Meeting length"))
                    Spacer()
                    Text("\(scrum.lengthInMinutes) minutes")
                }
                HStack {
                    Label("Color", systemImage: "paintpalette")
                    Spacer()
                    Image(systemName: "checkmark.circle.fill")
                        .foregroundColor(scrum.color)
                }
                .accessibilityElement(children: .ignore)
            }
            Section(header: Text("Attendees")) {
                ForEach(scrum.attendees, id: \.self) { attendee in
                    Label(attendee, systemImage: "person")
                        .accessibilityLabel(Text("Person"))
                        .accessibilityValue(Text(attendee))
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            DetailView(scrum: DailyScrum.data[0])
        }
    }
}

これでDetailViewは以下のような画面になっているはずです。

014

最後に、Start MeetingをタップしたらMeetingViewに遷移するようにしましょう。
Start MeetingにNavigationLinkを設定します。
また、この画面のタイトルを設定します。

import SwiftUI

struct DetailView: View {
    let scrum: DailyScrum

    var body: some View {
        List {
            Section(header: Text("Meeting Info")) {
                NavigationLink(destination: MeetingView()) {
                    Label("Start Meeting", systemImage: "timer")
                        .font(.headline)
                        .foregroundColor(.accentColor)
                        .accessibilityLabel(Text("Start meeting"))
                }
                HStack {
                    Label("Length", systemImage: "clock")
                        .accessibilityLabel(Text("Meeting length"))
                    Spacer()
                    Text("\(scrum.lengthInMinutes) minutes")
                }
                HStack {
                    Label("Color", systemImage: "paintpalette")
                    Spacer()
                    Image(systemName: "checkmark.circle.fill")
                        .foregroundColor(scrum.color)
                }
                .accessibilityElement(children: .ignore)
            }
            Section(header: Text("Attendees")) {
                ForEach(scrum.attendees, id: \.self) { attendee in
                    Label(attendee, systemImage: "person")
                        .accessibilityLabel(Text("Person"))
                        .accessibilityValue(Text(attendee))
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle(scrum.title)
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            DetailView(scrum: DailyScrum.data[0])
        }
    }
}

これでScrumsView->DetailView->MeetingViewと遷移できるようになりました。
アプリをbuildして確認してみましょう。


ここまでのまとめ

  • NavigationViewを使うと勝手に階層構造にしてくれる
  • NavigationLinkで遷移先を指定できる

次回はDetailViewから内容を編集できるようにします。
(やっと中盤です・・・)

Pocket

コメントを残す

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