links
アプリ概要
今回はとりあえず何か形あるものを作りたいと思い、ToDoリストの作成に取り組みました。 Swiftの予備知識がなくても、簡単に作成できると思います。
機能紹介
ここでは機能の紹介をしたいと思います。まずは起動直後の画面です。

レイアウトは至ってシンプルです。
上部左右にそれぞれ「削除」「追加」ボタンがあり、そこから、リストの追加や
削除を行います。
次に「追加」ボタン押下時の画面です。

この画面では、ToDoリストへタスクの追加を行います。
今回のデモ画像では、「洗濯」とありますが、そのテキストボックス内に
登録したいタスクを入力し、確定ボタンを押下することで、タスクが登録され、
自動でトップ画面へと戻ります。
また、空白での登録を受け付けず、タスクが必ず入力されていることを保証します。
さらに、タスクの登録を中断したい場合は左上の「<」ボタンを押下することで
登録作業を中断し、トップ画面に戻ることができます。
実際に確定ボタンを押下すると次の画像の様に、登録されたタスクが表示された
トップ画面が表示されます。

追加できました!!
他のタスクも追加してみましょう。

ここで、気がついた方もいると思いますが、タスクの左側に丸がありますね。
この丸はチェックリストになっており、タスク終了時にそのタスクを押下することで
終了の印のチェックがつきます。
実際に押下してみると...

このようにチェックがつきます。
チェックがついた状態で左上の「削除」ボタンを押下すると...

この様に、チェックしていたタスクが削除されました。
以上がこのToDoアプリの機能になります。簡単な構造ですが、ToDoリストに必要な
最低限のものは実現できました。
コード(全体)
以下がコードの全体像になります。
/ContentView
import SwiftUI
struct TaskData{
var title:String
var completed:Bool
var id = UUID()
}
struct ContentView: View {
@State var appendTask:Bool = false
@State var taskList:Array = []
@State var task:String = ""
@State var rowCnt:Int = 0
var body: some View {
if self.appendTask {
NavigationView{
List{
TextField("タスクを入力してください", text: $task)
HStack{
Spacer()
Button(action: {
print("確定")
if task != ""{
taskList.append(TaskData(title: task, completed: false))
task = ""
appendTask.toggle()
}
}){
Text("確定")
}.foregroundColor(Color.blue)
Spacer()
}
}.navigationTitle("追加")
.navigationBarItems(leading: Button(action: {
// print("戻る")
appendTask.toggle()
}){
Image(systemName: "lessthan")
})
}
}else{
NavigationView{
VStack{
List(0..<taskList.count, id:\.self){ index in
Button(action:{
// print("ボタンが押されたよ")
taskList[index].completed.toggle()
}){
HStack{
Image(systemName:taskList[index].completed ? "checkmark.circle.fill" : "circle")
Text(taskList[index].title)
}
}.foregroundColor(.black)
}.navigationTitle("ToDoリスト")
.navigationBarItems(leading: Button(action: {
self.rowCnt = taskList.count
for i in 0..<taskList.count{
print((self.rowCnt - 1) - i)
if taskList[(self.rowCnt - 1) - i].completed{
taskList.remove(at: (self.rowCnt - 1) - i)
}
}
}){
Text("削除")
}, trailing: Button(action: {
appendTask.toggle()
}){
Text("追加")
})
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
}
}
}
コード解説
ここでは、今回コードを作成するにあたって重要だと思った部分を抜粋して 解説します。
タスクの管理
タスクの管理は以下の様な構造体で管理しています。

変数の役割としては
title: タスク名
completed: 終了判定
id: 一意のID
といった感じです。Bool型のcompletedはチェックマークの表示に使用しています。
タスク作成時はfalseですが、押下することで、trueとなりチェックマークがつきます。
また、true時に押下するとチェックマークがはずれ、falseへと戻ります。
そのほかに用意した変数
そのほかに用意した変数としては以下のものが挙げられます。

変数の前に「@State」とついていますね。
これは、現時点での自分なりの解釈となってしまいますが、その変数の状態を
監視しているといった雰囲気です。
変数の状態の変化を認識してくれるので、今回は画面遷移に使用しました。
それでは、それぞれの変数についての説明です。
appendTask: 画面遷移用
taskList: 登録したタスクを管理するための配列
task: タスクのタイトルを保持するための変数
rowCnt: 現在登録されているタスクをカウントするための変数
といった内容になっています。
画面遷移はどうなってるの
画面遷移はどうなっているのでしょうか。
先ほどの変数の説明で、画面遷移用の変数「appendTask」がありました。
この変数とif文を組み合わせることで画面遷移をおこなっています。
プログラムを大きく分割してみてみましょう。

この2つのブロックはよくみるとif文によって分けられています。 コードを省力してみてみると...
if self.appendTask{
// タスク追加用画面
}else{
// Top画面
}
この様に、appendTaskがtrueの時は、タスク追加用画面が、 falseの時はTop画面が表示される様になっています。また、これらの条件分岐は 「@Status」により、appendTaskの値が変更されるたびに実行されます。
こだわりポイント
今回こだわった部分は、空白でのタスク追加を受け付けない機能です。

26~31行目のプログラムですが、task変数を使用することで、入力があったときのみ、配列へ追加し、 追加が終わった後には「""」によって初期化をおこなっています。単純な処理ですが、ToDoリストに おいてとても大事な処理だと思いました。
まとめ
簡単なプログラムで、比較的できの良いToDoリストが作成できたので、 アプリ作成の第一歩として楽しく作成できました。一方で、より実践的な開発手法や コーディングなど、基礎の知識では補えない部分があるので、あまり綺麗なアプリの作り方では ないのかなと思いました。また、改善点も多くあり、具体的には、アプリのタスクを切った時に 登録していたリストを保持することができず、初期化されてしまうバグがあります。このバグは、 端末自体にデータを保持するか、サーバで管理することで解決できるのではないかと考察しています。 今回のアプリ作成をきっかけに、設計手法やデータの保存方法など、コーディング以外の部分も学習 していこうと思いました。
《参考文献》
Listを使ってToDoリストを作ってみよう!
https://ios-docs.dev/swiftui-part10/
さまざまなSwiftUIの画面遷移について
https://yosshiblog.jp/swiftui_screen-transiton/