TIL 14

오늘 한 일 / 배운점

  • 개인 과제 Lv.2 (진행중)
  • 8/4 19:00 실시간 세션 : 옵셔널의 이해 (HH튜터님)

과제

  • 개인 과제 Lv.2

    • 오토 레이아웃 적용하기

    • UIButton 또는 UISegmentedControl 사용하여 할 일 완료/미완료 상태 만들기

    • 할 일 완료되면 가로선 넣는 등.. 완료/미완료 상태에 따라 UI 변경

    • 오토 레이아웃 적용하기 UIButton 또는 UISegmentedControl 사용하여 할 일 완료/미완료 상태 만들기 할 일 완료되면 가로선 넣는 등.. 완료/미완료 상태에 따라 UI 변경

느낀점

원래 오늘 계획했던 내용들은 하다가 또 다른 곳에 꽂혀서 자연스럽게 다음 주 월요일 계획으로 넘어갔다..
아래는 오늘 얻은 결과물

  1. 다른 뷰 컨트롤러를 갔다 와도 데이터가 남아있고 앱을 껐다 켜도 할 일이 날아가지 않도록
    → 이것은 UserDefaults를 사용하여 해결 가능했다
    이 UserDefaults라는 게 원래는 앱 설정, 사용자 기본값이나 임시 데이터 같은 거를 저장하는 용도라 간단한 데이터 저장에만 적합하다고 한다
    하지만 이번에는 간단한 과제기도 하고.. 배열 하나 정도 저장하는 거니 한번 써볼 겸 사용하기로
var toDoTasks = [String]() // TODO 입력값 저장하는 배열
let toDoTasksKey = "ToDoTasks" // ① UserDefaults Key값 설정

override func viewDidLoad() {
        super.viewDidLoad()
        // ② UserDefaults로부터 저장된 데이터 가져와서 toDoTask 배열에 넣기
        if let savedData = UserDefaults.standard.array(forKey: toDoTasksKey) as? [String] {
            toDoTasks = savedData
        }
}


class ToDoViewController: UIViewController {
                self.toDoTasks.append(inputText)
                self.emptyTasksUILabel.isHidden = true // 배열에 값이 추가되면 UILabel 가리기
                self.tableView.reloadData() // 테이블 뷰를 리프레시
                
                UserDefaults.standard.set(self.toDoTasks, forKey: self.toDoTasksKey) // ③ toDoTasks를 UserDefaults에 저장     

위와 같이 ① Key 값 설정 (바로 갖다 써도 되긴 하지만 코드 유지 보수성&가독성 위해 변수에 담아 준다)

let "(UserDefaults Key값)" = "UserDefaults Key값"

② 해당 Key 값으로 저장할 때

UserDefaults.standard.set(self."(UserDefaults에 넣을 값)", forKey: self."(UserDefaults Key값)")

③ 해당 Key 값으로 불러올 때

UserDefaults.standard.array(forKey: "(UserDefaults Key값)")

하면 앱이 종료되고 다시 실행해도 복원이 된다. 이렇게 간단할 수가!

  1. 할 일을 오른쪽으로 스와이프 하여 삭제 가능하도록

    → 흔히 앱에서 옆으로 스와이프 하면 쮸르륵 나오는 기능들 1

    위와 같은 것을 적용하고 싶었는데 역시나 찾아보니 있다
    UITableViewDataSource에서 제공하는 trailingSwipeActionsConfigurationForRowAt메서드를 이용하면 되는 것.
    이 메서드는 UITableView의 행(셀)을 오른쪽으로 스와이프 할 때 나타나는 뷰를 구성하는 데 사용된다.
    나는 꼬리 쪽에 달고 싶었는데 물론 leadingSwipeActionsConfigurationForRowAt를 사용하면 머리 부분에 달 수도 있다.

    extension ToDoViewController: UITableViewDelegate {
    
        // row를 오른쪽으로 스와이프 시 삭제 버튼 나오도록
        func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
            let delete = UIContextualAction(style: .destructive, title: nil) { (_, _, success) in
                self.toDoTasks.remove(at: indexPath.row) // toDoTasks배열에서 해당 row와 같은 값 삭제
                UserDefaults.standard.set(self.toDoTasks, forKey: self.toDoTasksKey) // toDoTasks배열을 UserDefaults에 반영
                tableView.reloadData()// 테이블 뷰 리로드
                success(true)        
            }
            delete.backgroundColor = .red
            delete.image = UIImage(systemName: "trash")
    
            return UISwipeActionsConfiguration(actions: [delete])
        }
    }
    

    위와 같이 row를 밀었을 때 빨간 배경에 휴지통 모양의 아이콘이 나오고
    그것을 클릭하면 toDoTasks 배열에서 해당 indexPath.row의 값을 찾아 삭제하고
    그 toDoTasks 배열을 그대로 UserDefaults에 반영시키는 식으로 처리했다.

    *처음에는 눌렀을 때 실행되는 이벤트 같은 거니까 UITableViewDelegate 내부에 위치시켰는데
    일반적으로 스와이프 액션은 데이터 변경에 관련된 기능이므로 UITableViewDataSource에 놓는 게 적합하다 해서 다시 변경했다

  2. 할 일이 없을 때는 할 일을 추가하라고 메시지를 표시
    → toDoTasks 배열 감시하여 배열에 아무 값이 없으면 표시하고 값이 추가되면 사라지게 하고 싶었는데

      var toDoTasks = [String]()
    

    아래와 같이 didSet을 사용하여 내가 원하는 것을 구현할 수 있었다

    
      var toDoTasks = [String]() {
          didSet { // didset: toDoTask에 변화가 감지되면 아래 코드블럭이 호출된다
              if toDoTasks.isEmpty {
                  self.emptyTasksUILabel.isHidden = false // 배열이 비어있으면 UILabel 숨기기
              } else {
                  self.emptyTasksUILabel.isHidden = true // 배열에 값이 있으면 UILabel 보이기
              }
          }
      }
    
  3. 오토레이아웃

    오토 레이아웃은 정말 간단해 보이는데 지금도 모르겠다(그래서 스위프트 하면 오토 레이아웃이란 말이 심심치 않게 보였나 보다)
    야금 유튜브 강의 이것저것 보면서 따라 해봤는데 그 예제를 하나하나 똑같이 따라 하면 잘 되는데
    내가 놓은 요소들을 내가 원하는.. 머릿속에 있는 걸 직접 해보면 다른 제약이랑 겹쳐서 빨간 줄 뜨고 난리 ㄱ-

    2
    일단 두 개의 버튼의 사이를 간격을 지정하고 Stack View로 묶고 Horizontal , Vertical 모두 중앙으로 박고.. 어찌어찌해서 맞췄다
    사실 이 간단한 거 하는데도 뭐가 계속 충돌 나고 어떻게 했는지 기억도 안 나지만.. 이젠 빨간색 선도 안 뜨고

    3
    이렇게 화면을 가로세로 전환해도 잘 적용되는 것을 확인할 수 있다
    근데 이게 과연 바람직하게 맞춘 건지 모르겠다 -_-;
    오토 레이아웃은 좀 더.. 공부할 필요가 있는 것 같다.