[iOSアプリ開発初期格差コース]Part 2.To Do Listアプリケーションの作成
44120 ワード
To Do Listアプリケーション
Intro
[機能の説明]
→TableViewに保留を追加できる
→Table Viewでの保留を削除する
→Table Viewでは、やるべきことを再スケジュールできます
→やるべきことをデータベースに保存し、アプリケーションを再実行してもデータを保持できるようにする
[使用するテクノロジー]
→ UITableView
→ UIAlertController
→ UserDefaults
TableView
最も基本的なUIコンポーネントは、
→Table Viewを使用するために必要なプロトコル
→UItableViewDelegate:Table Viewの表示部分の設定、行のアクション管理、ヘルパービューのサポート、およびTable Viewの各行の編集を支援する
→UItableViewDataSource:TableViewオブジェクトの作成と変更に必要な情報
UITableViewDelegate
// 행이 선택되었을 때 호출되는 메소드
optional func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
// 행이 선택 해제되었을 때 호출되는 메소드
optional func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
// 특정 위치 행의 높이를 묻는 메소드
optional func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
// 지정된 섹션의 헤더뷰 또는 풋터뷰에 표시할 View가 어떤 것인지 묻는 메소드
optional func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
optional func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
// 지정된 섹션의 헤더뷰 또는 풋터뷰의 높이를 묻는 메소드
optional func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
optional func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
// 테이블뷰가 편집 모드에 들어갔을 때 호출되는 메소드
optional func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath)
// 테이블뷰가 편집 모드에서 빠져나왔을 때 호출되는 메소드
optional func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?)
// 테이블뷰가 셀을 사용하여 행을 그리기 직전에 호출되는 메소드
optional func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
// 테이블뷰로부터 셀이 화면에서 사라지면 호출되는 메소드
optional func tableView(_ tableView: UITableView, didEndDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
UITableViewDataSource
// 각 섹션에 표시할 행의 개수를 묻는 메소드(필수)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// 특정 인덱스 Row의 Cell에 대한 정보를 넣어 Cell을 반환하는 메소드(필수)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// 총 섹션 개수를 묻는 메소드
optional func numberOfSections(in tableView: UITableView) -> Int
// 특정 섹션의 헤더 타이틀을 묻는 메소드
optional func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
// 특정 섹션의 풋터 타이틀을 묻는 메소드
optional func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
// 특정 위치의 행이 편집 가능한지 묻는 메소드
optional func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// 특정 위치의 행을 재정렬할 수 있는지 묻는 메소드
optional func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
// 테이블 뷰 섹션 인덱스 타이틀을 묻는 메소드
optional func sectionIndexTitles(for tableView: UITableView) -> [String]?
// 인덱스에 해당하는 섹션을 알려주는 메소드
optional func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int
// 스와이프 모드, 편집 모드에서 버튼을 선택하면 호출되는 메소드
// 해당 메소드에서는 행의 변경 사항을 Commit해야 함
optional func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
// 행이 다른 위치로 이동되면 어디서 어디로 이동했는지 알려주는 메소드
optional func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
きのうインプリメンテーション
//
// ViewController.swift
// ToDoList
//
// Created by TAEJANIM on 2021/11/09.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet var editButton: UIBarButtonItem!
var doneButton: UIBarButtonItem?
var tasks = [Task]() {
didSet {
self.saveTasks()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTap))
self.tableView.dataSource = self
self.tableView.delegate = self
self.loadTasks()
}
@objc func doneButtonTap() {
self.navigationItem.leftBarButtonItem = self.editButton
self.tableView.setEditing(false, animated: true)
}
@IBAction func tapEditButton(_ sender: UIBarButtonItem) {
guard !self.tasks.isEmpty else { return }
self.navigationItem.leftBarButtonItem = self.doneButton
self.tableView.setEditing(true, animated: true)
}
@IBAction func tapAddButton(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "할 일 등록", message: nil, preferredStyle: .alert)
let registerButton = UIAlertAction(title: "등록", style: .default, handler: { [weak self] _ in
guard let title = alert.textFields?[0].text else { return }
let task = Task(title: title, done: false)
self?.tasks.append(task)
self?.tableView.reloadData()
})
let cancelButton = UIAlertAction(title: "취소", style: .cancel, handler: nil)
alert.addAction(cancelButton)
alert.addAction(registerButton)
alert.addTextField(configurationHandler: { textField in
textField.placeholder = "할 일을 입력해주세요."
})
self.present(alert, animated: true, completion: nil)
}
func saveTasks() {
let data = self.tasks.map {
[
"title": $0.title,
"done": $0.done
]
}
let userDefaults = UserDefaults.standard
userDefaults.set(data, forKey: "tasks")
}
func loadTasks() {
let userDefaults = UserDefaults.standard
guard let data = userDefaults.object(forKey: "tasks") as? [[String: Any]] else { return }
self.tasks = data.compactMap {
guard let title = $0["title"] as? String else { return nil }
guard let done = $0["done"] as? Bool else { return nil }
return Task(title: title, done: done)
}
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let task = self.tasks[indexPath.row]
cell.textLabel?.text = task.title
if task.done {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
self.tasks.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
if self.tasks.isEmpty {
self.doneButtonTap()
}
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var tasks = self.tasks
let task = tasks[sourceIndexPath.row]
tasks.remove(at: sourceIndexPath.row)
tasks.insert(task, at: destinationIndexPath.row)
self.tasks = tasks
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var task = self.tasks[indexPath.row]
task.done = !task.done
self.tasks[indexPath.row] = task
self.tableView.reloadRows(at: [indexPath], with: .automatic)
}
}
//
// Task.swift
// ToDoList
//
// Created by TAEJANIM on 2021/11/09.
//
import Foundation
struct Task {
var title: String
var done: Bool
}
Outro
→1列と複数行で垂直スクロールのみ
→UItableViewDataSource:データを受信してビューを描画する役割
→UItableViewDelegate:
結果
Reference
この問題について([iOSアプリ開発初期格差コース]Part 2.To Do Listアプリケーションの作成), 我々は、より多くの情報をここで見つけました https://velog.io/@taejanim/iOS-앱개발-초격차-패키지-Part-2.-To-Do-List-앱-만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol