본문 바로가기
Dot/iOS

iOS) Realm을 이용한 Swift Todo 앱 만들기 (1)

by jum0 2020. 5. 7.

먼저, 새로운 프로젝트를 생성해줍니다.

그리고는 Main.storyboard로 바로 뛰어갑니다.

왜냐하면 우리는 기본 View Controller를 사용하지 않고 Table View Controller로 앱을 만들 거거든요.

반드시 Table View Controller로 만들어야 하는 것은 아닌데, datasourcedelegate가 이미 연결되어 있어 View Controller에 Table View와 Table View Cell을 추가해서 연결하는 것보다 쪼금 더 편합니다.(라고 쓰고 이렇게 배워서라고 합니다..ㅎ)

아무튼 추가하고 처음 View Controller를 없애기 전에 화살표(앱이 처음 시작할 화면)를 옮겨주세요.

Table View Controller를 클릭한 후, 오른쪽의 Is Initial View Controller를 체크하거나 기본 View Controller에서 화살표를 드래그해서 옮겨주면 됩니다.

옮겼으면 View Controller는 안녕... 다음에는 좋은 앱이 되길 바라... (대충 삭제하라는 말)

이제 ViewController.swift 파일로 가서 정리 좀 해보겠습니다.

Super Class를 UIViewController에서 UITableViewController로 바꿔줍니다. Class와 파일명은 TodoListViewController로 할래요.(절대 초심자라서 순순히 하라는 대로 하는 것 아님. 암튼 아님.)

이제 다시 Main.storyboard로 갑니다.

Table View ControllerCustom Class를 ViewController.swift에서 이름이 바뀐 TodoListViewController로 지정해줍니다. 

그럼 이렇게 됩니다. 짜잔!@

알아서 Controller 이름도 바뀜 올ㅋ

됐고 다음은 cell의 Identifier를 정해줄 거예요. 뜻 그대로 식별자입니다. 너, 그, 야, 쟤, 이런 거 말고 우리의 친구 cell에게 이름을 지어줄 거예요. 근데 이름을 cell로 지어줬어요. 유튜브에서 본 영상이 갑자기 스쳐가서. 그냥 기억할 수 있는 대로 지어줍시다. (나중에 바꿀 수도 있음)

다음으로는 Editor(사진에서 잘림) - Embed In - Navigation Controller를 눌러주세요. 우리는 내비게이션 타고 노는 앱이니까요.

이제 제목도 붙여주고 내비게이션 색을 이쁘게 살짝 칠해줘 볼게요.

Title은 Todo List View Controller의 Navigation Item(사진은 Title을 지정해서 바뀜)을 눌러 변경할 수 있고, 색은 위 사진의 빨간 네모를 클릭한 후 Bar Tint에서 변경할 수 있습니다.

이제 본격적으로 코드를 짜 볼게요.

먼저 TodoListViewController.swift로 이동합니다.

그리고 다음과 같이 추가할게요!

//TodoListViewController.swift

import UIKit

class TodoListViewController: UITableViewController {
    
    let category = ["Home", "Library", "Coin"]

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return category.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        cell.textLabel?.text = category[indexPath.row]
        
        return cell
    }

}

일단 데이터를 테이블에 띄우기 위해서 category 리스트를 만들어줬어요. 리스트는 집, 도서관, 코인 노래방입니다. (취준생의 삶이 그대로 드러납니다.. 아 코로나 때문에 코인 노래방은 희망 사항으로 넣어봤어요.. 가고 싶다.. 흐흑)

리스트 설명은 됐고, 저 두 메서드 numberOfRowsInSectioncellForRowAt는 테이블을 띄우기 위해서 필수적인 메서드입니다.

numberOfRowsInSection은 테이블에 나타낼 열(줄)의 개수를 리턴 값으로 가져요. 저희는 category 리스트의 원소의 개수만큼 뽑을 예정이니깐 리스트의 개수를 return 값으로 합니다.

cellForRowAt는 딱 뭐다라고 말하지 못하니깐 정확한 의미를 파악하기 위해서 바로 Documentation을 확인해보겠습니다!

지정된 index path에 있는 테이블 셀을 반환한다네요. 

아니 index path가 뭔데요,,

다시 한번 찾아보니 이렇게 나와있어요.

중첩된 Array의 트리의 특정 위치에 대한 path와 함께 나타내는 인덱스의 목록.

흠.. 솔직히 무슨 말인지 잘 안와닿네요...ㅎ

그래서 우리 구글 형님께 아뢰보니, IndexPath는 함수가 요청하는 섹션의 행에 대한 정보가 있고, 이 숫자를 기준으로 주어진 행에 대한 데이터를 표시하도록 셀을 구성한다고 합니다.

오 무슨 말인지 좀 이해가 되네요. 아 참고로 섹션은 노란색 동그라미임. 위에서부터 0, 1, 2...

마지막으로 궁금하니깐 indexPath를 프린트해봤는데 이런 값이 나왔어요.

오 우리가 방금 만든 셀들은 섹션 구분이 따로 없으니깐 처음 값인 0이고 열(줄)이 차례로 0, 1, 2 군요. 오호. 그리고 우리가 나타낸 셀은 총 3개니깐 cellForRowAt 메서드가 세 번 호출이 되었어요. 신기하네요!(가식)

아 코드 보면서 설명하는데, 너무 올라가서 cellForRowAt 메서드만 다시 가져와볼게요.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
    cell.textLabel?.text = category[indexPath.row]
        
    return cell
}

안에 dequeReusableCell 메서드는 재사용이 가능한 테이블 뷰의 셀 객체를 반환한다고 합니다. 즉, 셀이 많아지면 그만큼 많은 메모리를 차지하게 되는데 이 메서드로 셀을 다시 재사용을 할 수 있어요! 어떻게 하냐? 많은 셀들이 있을 때 스크롤을 내리면 화면 위로 사라진 애들을 다시 써먹는 방식으로요.

그래서 셀을 이 메서드로 선언해주고 withIdentifier에는 우리가 아까 셀에게 지어 주었던 이름을, for에는 indexPath를 그대로 사용합니다!

셀의 텍스트에 category 리스트의 원소를 이름으로 줄건데, indexPath.section을 뽑아보면 아까 indexPath를 프린트했을 때 나오는 리스트의 0번 째 원소가 나오고, indexPath.row(열 번호)는1번 째 원소가 나와요. 그래서 indexPath.row를 이용합니다!

그리고 cell을 반환해주면 다음과 같이 나옵니다!

테이블 하나 띄우는데 뭔가 되게 힘든 이 느낌은 뭐죠?ㅋㅋ

힘드니깐 일단 쉬고! 다음 포스트에서 이어서 계속 해볼게요!


전체 코드

//TodoListViewController.swift

import UIKit

class TodoListViewController: UITableViewController {
    
    let category = ["Home", "Library", "Coin"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    //MARK: - TableView Datasource Methods
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return category.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        cell.textLabel?.text = category[indexPath.row]
        
        print(indexPath)
        
        return cell
    }
}

수정해야 할 부분이 있으면 알려주세요!

감사합니다!

반응형

댓글