ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS - memo 앱 만들기 #8 데이터 전달
    iOS 2020. 12. 15. 21:56

     memo 앱 만들기 #8 데이터 전달

     

     

    지금은 목록화면과 세부화면이 segue로 연결되어 있고 segue는 연결된 화면을 자동으로 만들어준다.

     

    그리고 네비게이션 컨트롤러가 이 화면을 자동으로 푸쉬해준다.

     

    하나의 화면에서 다른 화면으로 데이터를 전달해주는 방법은 여러가지가 있는데

     

    여기에서는 가장 기본적인 패턴으로 구현

     

    segue는 화면을 만들고 화면전환이 시작되기 전에 특별한 메소드를 호출한다.

     

    여기서 선택한 메모를 전달하는 방식으로 구현!

     

    [DetailViewControllr.swift]

    class DetailViewController: UIViewController {
    
        // ViewController가 초기화되는 시점에는 값이 없기때문에 옵셔널(?) 로 선언
        // 여기에는 이전화면에서 전달한 메모가 저장된다.
        var memo: Memo?
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
        }

     

    여기서는 왼쪽의 목록 화면이 segue를 생성한 sender가 된다.

     

    그리고 이 센더는 아래의 메소드 두번째 파라미터로 전달된다.

     

    [MemoListTableViewController.swift]

     // segue가 연결된 화면을 생성하고 화면을 전환하기 직전에 호출
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            <#code#>
        }

    이 sender를 활용해서 몇번째 cell을 선택했는지 계산해야 한다.

     

    sender의 자료형을 살펴보면 옵셔널 Any로 선언되어 있는데 이걸 실제 우리가 보내주는 자료형인 UITableViewCell으로 바꾸고

     

    cell을 tableView로 전달해서 몇번째 위치에 있는 cell인지 확인

     

    // segue가 연결된 화면을 생성하고 화면을 전환하기 직전에 호출
        // 첫번째 파라미터로 현재 실행중인 segue가 전달된다.
        // 여기(첫번째 파라미터) 에서 목록화면과 보기화면에 접근할 수 있다.
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let cell = sender as? UITableViewCell, let indexPath = tableView.indexPath(for: cell){
                
                // segue를 실행하는 화면
                segue.source
                
                // 새롭게 표시되는 화면
                segue.destination
            }
        }

     

    segue.source와 segue.destination 둘다 리턴타입이 UIViewController이기 때문에 우리에게 맞는 DetailViewController 타입으로

     

    캐스팅해야한다.

     

    // segue가 연결된 화면을 생성하고 화면을 전환하기 직전에 호출
        // 첫번째 파라미터로 현재 실행중인 segue가 전달된다.
        // 여기(첫번째 파라미터) 에서 목록화면과 보기화면에 접근할 수 있다.
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let cell = sender as? UITableViewCell, let indexPath = tableView.indexPath(for: cell){
                
                if let vc = segue.destination as? DetailViewController{
    				// 배열에서 선택한 값을 가져와서 memo속성에 저장
                    vc.memo = Memo.dummyMemoList[indexPath.row]
                }
                // segue를 실행하는 화면
                //segue.source
                
                // 새롭게 표시되는 화면
                //segue.destinatio
            }
        }

     

     

    이어서 목록화면에서 전달한 메모를 보기화면에서 출력

     

    [DetailViewController] 

     

    여기에 저장된다

        var memo: Memo?
    

     

    let formatter: DateFormatter = {
            let f = DateFormatter()
            f.dateStyle = .long
            f.timeStyle = .short
            f.locale = Locale(identifier: "Ko_kr")
            return f
        }()

     

    코드를 추가하고

     

    cell에 어떤 데이터를 넣을건지 밑과 같이 추가한다.

    extension DetailViewController: UITableViewDataSource{
        
        // 표시할 셀 숫자를 리턴해주는 메소드
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 2
        }
        
        
        // tableView가 어떤 cell을 표시할지 나타내는 메소드
        //
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            switch indexPath.row {
            // 첫번째 cell
            case 0:
                let cell = tableView.dequeueReusableCell(withIdentifier: "memoCel", for: indexPath)
                
                cell.textLabel?.text = memo?.content
                
                // 날짜를 표시
                // 날짜를 표시하려면 문자로 바꿔야하고 그러려면 dateFomatter를 사용
                // 이전에는 그냥 .string을 썼는데 이건 ? (옵셔널) 을 포함할 수 없기때문에 밑에와 같이 string(for) 메소드를 사용한다.
                
                return cell
                
            case 1:
                let cell = tableView.dequeueReusableCell(withIdentifier: "dateCel", for: indexPath)
                cell.textLabel?.text = formatter.string(for: memo?.insertDate)
                return cell
            default:
                fatalError() // 에러발생
            }
        }
        
        
    }
    

    댓글

Designed by Tistory.