ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS - memo 앱 만들기 #1 테이블 뷰 구현 이론
    iOS 2020. 12. 15. 14:06

    1. 테이블 뷰 배치

     

     Navigation Controller 이용

     

    2. 프로토 타입 셀 디자인, 셀 아이덴티파이어 지정

     

    3. 데이터 소스, 델리게이트 연결

     

    * 이전에 swift 파일을 만들어 직접 UITableVIewCell 을 extension 해줘 메소드를 만든 방식과는 다르게

     

    이번엔 Cocoa touch Class를 만들어 UITableVIewController을 Subclass로 하여 파일 생성(UITableViewDataSource가 포함되어 있는 것 같음)

     

     

    생성한 파일을 storyBoard와 연결해주고 

     

    4. 데이터 소스 구현

    import UIKit
    
    class MemoListTableViewController: UITableViewController {
        let formatter: DateFormatter = {
            let f = DateFormatter()
            f.dateStyle = .long
            f.timeStyle = .short
            f.locale = Locale(identifier: "Ko_kr")
            return f
        }()
        
        // 뷰 컨트롤러가 관리하는 뷰가 화면에 표시되게 직전에 자동으로 호출
        // 근데 viewWillAppear 메소드는 full screen에서만 자동으로 호출되고 ios 13이상의 기본값인 sheet에서는 호출되지 않는다 -> notification을 이용해야 한다
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            
            // reloadData -> 데이터소스가 전달해주는 최신 데이터로 업데이트
    //        tableView.reloadData()
    //        print(#function)
        }
        
        
        var token : NSObjectProtocol?
        
        
        // 소멸자에서 옵저버 해제
        deinit {
            if let token = token{
                NotificationCenter.default.removeObserver(token)
            }
        }
        
        
        // viewController가 호출될때 자동으로 호출된다. -> 주로 한번만 실행되는 초기화 코드 실행
        override func viewDidLoad() {
            super.viewDidLoad()
            // observer를 실행하는건 한번만 실행하면되서 보통 여기에 한다
            
            //첫번쨰 파라미터로 옵저버를 추가할 notification의 이름
            // Notification은 브로드캐스팅
            //두번째 는 특별한 이유가없으면 대부분 nil
            
            // ui를 업데이트 코드는 반드시 메인쓰레드에서 실행해야한다.
            // ios는 쓰레드를 직접 처리하지않고 dispatchQueue나 OperationQueue를 통해 처리한다.
            // 세번째 파라미터로 queue: OperationQueue.main 를해주면 옵저버가 처리하는 쓰레드가 메인 쓰레드에서 처리된다.
            // 마지막 파라미터에는 closer를 전달한다.
            // notification이 전달되면  네번째 파라미터로 전달된 클로저가 세번째 파라미터로 전달한 쓰레드에서 실행된다.
             
            // notification을 구현하는 코드에서 가장 중요한건 observer를 해제하는것! -> 해제안해도 실행은되지만 내부에서 메모리가 낭비되고 있다.
            // 지금 밑의 .addObserver()는 옵저버를 해제할수잇는걸 리턴해주는데 보통 이걸 토큰이라 부름
            // viewDidLoad에서 추가한 옵저버는  뷰가 화면에서 사라지기 전에 해제하거나 소멸자에서 해제하는데 여기에서는 소멸자에서 해제하겠다
            token = NotificationCenter.default.addObserver(forName: ComposeViewController.newMemoDidInsert , object: nil, queue: OperationQueue.main) { [weak self](noti) in
                self?.tableView.reloadData()
            }
            
            // Uncomment the following line to preserve selection between presentations
            // self.clearsSelectionOnViewWillAppear = false
    
            // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
            // self.navigationItem.rightBarButtonItem = self.editButtonItem
        }
    
        // MARK: - Table view data source
    
    //    override func numberOfSections(in tableView: UITableView) -> Int {
    //        // #warning Incomplete implementation, return the number of sections
    //        return 0
    //    }
        
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // #warning Incomplete implementation, return the number of rows
            return Memo.dummyMemoList.count
            
            // 테이블뷰가 몇개의 cell을 표시해야하는지 리턴해주는 부분
        }
    
        // 테이블뷰는 어떤 디자인으로 어떤 내용을 표시해야하는지 알려주는 메소드
        // 개별셀을 호출할때마다 이 메소가 호출됨
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
            // cell 이라는 identifier를 가져와서 생성 (이때는 비어있음)
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            
            
            // let cell에 우리가 만든 cell이 들어간다
            
            // Configure the cell...
            let target = Memo.dummyMemoList[indexPath.row]
            
            // subtitle에는 밑에 두개의 속성이 존재
            cell.textLabel?.text = target.content
            cell.detailTextLabel?.text = formatter.string(from: target.insertDate )
    //        cell.detailTextLabel?.text = target.insertDate.description
    
            return cell
        }
        
    
        /*
        // Override to support conditional editing of the table view.
        override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
            // Return false if you do not want the specified item to be editable.
            return true
        }
        */
    
        /*
        // Override to support editing the table view.
        override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
            if editingStyle == .delete {
                // Delete the row from the data source
                tableView.deleteRows(at: [indexPath], with: .fade)
            } else if editingStyle == .insert {
                // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
            }    
        }
        */
    
        /*
        // Override to support rearranging the table view.
        override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
    
        }
        */
    
        /*
        // Override to support conditional rearranging of the table view.
        override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
            // Return false if you do not want the item to be re-orderable.
            return true
        }
        */
    
        /*
        // MARK: - Navigation
    
        // In a storyboard-based application, you will often want to do a little preparation before navigation
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            // Get the new view controller using segue.destination.
            // Pass the selected object to the new view controller.
        }
        */
    
    }

     

     

    5. 델리게이트 구현

     


     

    'iOS' 카테고리의 다른 글

    iOS - memo 앱 만들기 #3 취소 기능  (0) 2020.12.15
    iOS - memo 앱 만들기 #2 새 메모 쓰기 화면  (0) 2020.12.15
    ios - tableView  (0) 2020.12.14
    iOS - Password AutoFill  (0) 2020.12.14
    iOS - Remote Notification  (0) 2020.12.14

    댓글

Designed by Tistory.