💡 Goal : 메모앱(My Todo List) 만들기
어느덧 프로그래밍 주차가 끝나고 앱개발 입문 주차이다.
앱개발 첫 과제인 이번주차 과제는 *메모앱 TodoList* 만들기이다! 요구사항을 따라 기본 기능들을 구현하며 어려웠던 점들과 해결한 과정을 정리해보려 한다.
features: 기능 목록
- LV1. Todo List 화면 만들기
- LV2. Todo 추가 및 완료 기능 구현하기
- LV3. Todo 삭제 기능 구현하기
프로젝트 준비
Xcode를 시작하고 iOS 프로젝트를 원하는 이름으로 생성해 준다.
UI 구성하기
완성 화면
👉 완성된 화면은 다음과 같고 UI 구성은 과제 예시와 같도록 간단하게 구현했다.
초기 화면의 우측 상단에는 할 일을 추가할 수 있는 +버튼이 있다. +버튼을 누르면 할 일을 추가할 수 있는 Alert창이 뜨고 그 안에 TextField 안에 내용을 작성할 수 있다. 할 일 우측에 switch 버튼을 누르면 텍스트에 취소선이 생기며 완료됐다는 표시를 할 수 있다. 또한 왼쪽으로 스와이프해서 삭제가 가능하게끔 설정을 해두었다.
스토리보드로 뷰컨트롤러에 할 일을 보여줄 수 있도록 table View를 추가했다.또한 table View 안에 add(+) 버튼도 추가해 줬다.
table View 안의 Cell 에는 Label과 Switch 컴포넌트들을 추가하고 오토레이아웃을 잡아줬다!
ViewController.swift 기능 구현하기
TableView로 화면 구성하기
// MARK: - Table view data source
extension TodoTableViewController: UITableViewDataSource {
// 한 section에 몇개의 row
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return todoData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TodoTableViewCell", for: indexPath) as! TodoTableViewCell
let todo = todoData[indexPath.row]
cell.setData(todo)
cell.todoLabel.sizeToFit()
return cell
}
}
UITableViewDataSource 프로토콜을 채택하여 TableView의 데이터를 표시하기 위한 필수적인 메서드들을 작성했다.
- numberOfRowsInSection(_:) : 행의 개수 반환
- cellForRowAt(_:) : 특정 위치 해당하는 셀 반환
- 이때 UITableViewCell을 커스텀 클래스로 다운캐스팅해줌! ( UITableViewCell이 상위 클래스)
이어서 TableView의 delegate와 dataSource를 현재의 ViewController로 설정하는 것도 잊지 말자!!
Todo 데이터의 구조는 식별아이디(id), 제목(title), 완료여부(isComplited)를 포함한다.
또한 생성된 할 일의 id를 자동으로 생성할 수 있는 초기화 메서드를 추가해줬다. 이때, ID는 TodoData의 정적 변수인 nextId로 설정되며 생성된 할 일 항목의 ID가 설정되면 nextId는 1 증가한다.
TodoTableViewCell 클래스는 UITableViewCell을 상속하며, setData() 메서드 구현은 TodoData 객체를 매개변수로 받아와서 셀의 UI를 설정해주는 역할을 한다.
할 일 추가하기: tapAddButton
간단한 ui를 구성했으니 할 일 추가 기능을 만들어보자. add(+) 버튼을 누르면 alert창을 띄워 추가되도록 만들 것이다.
@IBAction func tapAddButton(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "할 일 추가", message: "할 일을 입력해주세요", preferredStyle: .alert)
// 버튼 객체
alert.addTextField { (myTextField) in
myTextField.placeholder = "todo"
}
let registerButton = UIAlertAction(title: "등록", style: .default) { (_) in
// 등록 코드 작성
guard let title = alert.textFields?[0].text else { return }
let todo = TodoData(title: title)
self.todoData.append(todo)
self.todoTableView.reloadData()
}
let cancel = UIAlertAction(title: "취소", style: .cancel)
alert.addAction(registerButton)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
버튼이 탭 되었을 때 실행되는 액션 메서드이다.
우선 UIAlertController를 생성하고 제목은 "할 일 추가"로, 메시지는 "할 일을 입력해주세요"로 설정한다.
그리고 할 일을 입력받기 위한 addTextField(completion:) 메서드를 사용하여 텍스트 필드를 추가한다. 이때, configurationHandler의 파라미터 부분에 해당 매개변수를 입력해주고 placeholder를 작성했다.
이제 등록 액션과 취소 액션을 추가해주자.
UIAlertAction을 생성하여 "등록"이라는 제목, 스타일은 .default로 설정한다. 클로저 내에서는 사용자가 입력한 텍스트를 가져와서 새로운 TodoData 객체를 생성하고, 이를 todoData 배열에 추가한 후 테이블 뷰를 다시 로드한다.
취소 버튼도 마찬가지로 UIAlertAction을 생성하여 "취소"라는 제목, 스타일은 .cancel로 설정한다.
할 일 완료하기 : UILabel에 취소선
Cell에 있는 UISwitch를 이용하여 완료 여부를 확인하는 기능을 만들어보자.
예시 화면처럼 완료 상태에 따라 label에 취소선을 넣어주려 한다.
- NSAttributedString
import UIKit
extension String {
// 취소선 추가 메서드
func strikeThrough() -> NSAttributedString {
let attributeString = NSMutableAttributedString(string: self)
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0, attributeString.length))
return attributeString
}
// 취소선 제거 메서드
func removeStrikeThrough() -> NSAttributedString {
let attributeString = NSMutableAttributedString(string: self)
attributeString.removeAttribute(NSAttributedString.Key.strikethroughStyle, range: NSRange(location: 0, length: attributeString.length))
return attributeString
}
}
문자열에 취소선을 긋기 위해 NSAttributedString을 사용한다.
NSAttributedString은 문자열과 문자열에 대한 Attribute들에 대한 정보를 갖고 있는 객체이며 다양한 작업을 할 수 있다.
나는 취소선을 긋기 위한 메서드들을 String 타입의 extension을 통해 추가해준 뒤 사용했다.
📜 자세한 내용은 아래 문서 확인해보기!
스위치의 상태에 따라 함수를 적용해주면 해결된다!
할 일 삭제하기
이제 마지막인 삭제 기능을 구현해보자.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
self.todoData.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
셀의 삭제 버튼을 탭하여 셀을 삭제하려고 할 때 호출되는 commit editingStyle(_:forRowAt:):를 구현했다.
todoData 배열에서 해당 위치의 항목을 제거하고, 그에 해당하는 행을 UITableView에서 삭제한다.
시연 화면
이제 기능이 잘 동작하는지 실행해보자!
과제의 기본 기능은 완료했으니 추가 기능을 고민하고 구현해 봐야겠다🤗
'TIL✏️' 카테고리의 다른 글
[iOS] Swift로 TodoList App 만들기(3) - 카테고리 추가 (2) | 2024.03.27 |
---|---|
[iOS] Swift로 TodoList App 만들기(2) - 취소선, UserDefaults 데이터 저장 (5) | 2024.03.26 |
[Swift] 숫자 야구 게임 (1) | 2024.03.18 |
[Swift] Calculator 기능 구현하기 (1) | 2024.03.18 |
[WIL] 스린이들 - KPT회고 (2) | 2024.03.06 |