Archive/Doit 아이폰 앱(입문)

Table - 코드리뷰 ( 테이블뷰컨트롤러 )

lgvv 2021. 3. 2. 13:35

테이블 뷰 -- 이거 진짜 많이 사용할 것 같은데, 주석 통해서 확실히 알아두기

 

아 그리고 이건 갑자기 생각나서 적는건데 IBOutlet에 직접 전달할 수가 없어서

따로 변수 선언해서 연결해 주어야한다.

 

테이블 뷰 보면 저기 계속 줄이 보이죠? 근데 저거 있으면 불편하잖아요 그쵸? 그러면 어떻게 해결해야 하냐면

테이블 뷰의 프로토타입 아래에 view를 하나 넣어주면 테이블 뷰에서 내용이 없을 때, 더이상 표시되지 않아요! -- 꿀팁

 

테이블 뷰 사용법은,, 워낙 중요할 것 같다는 생각이 들어서 우선 살펴보도록 하자.

 

주석보면서 복습하면 쉬움

 

그래도 사용법 간단정리는 하고 지나갈까요?

테이블 뷰 기초 사용법

 1. 데이터소스 및 델리게이션 class쪽에 작성

 2. 그 이후는.. 함수 금방 이해할 수 있음.

 

아 근데 여기서 basic 개념 추가

 

만약 내 데이터가 200개고 화면에 10개만 표시된다고 하면 

재사용큐인가? 여튼 재사용하게 되는데

화면에 표시되는 것만 메모리에 올리고 나머지는 올리지 않는다. 화면에 나타나야 할때 또 메모리에 올리고

사라지는 것은 재사용큐에 넣어서 갖고 있는 것으로 알아

iOS가 메모리가 적어도 잘 관리하는데는 이런 이유가 있다고 해

거두절미하고, 이 개념은 내 깃허브 Basic 편을 가면 공부한 코드가 있으니까 직접 찾아보도록 

아니면 나중에 서술하도록 할게

테이블 뷰 자주쓰죠?

 

 

//
//  DetailViewController.swift
//  Table
//
//  Created by Hamlit Jason on 2021/02/25.
//

import UIKit

class DetailViewController: UIViewController {

    var receiveItem = ""
    
    @IBOutlet var lblItem: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        lblItem.text = receiveItem
        // Do any additional setup after loading the view.
    }
    
    func receiveItem(_ item : String){
        receiveItem = item
    }

    /*
    // 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.
    }
    */

}
//
//  AddViewController.swift
//  Table
//
//  Created by Hamlit Jason on 2021/02/25.
//

import UIKit


let MAX_ARRAY_NUM = 3
let PICKER_VIEW_COMUMN = 1
let PICKER_VIEW_HEIGHT:CGFloat = 40
var imageArray = [UIImage?]()
var imageFileName = [ "cart.png", "clock.png", "pencil.png" ]
var fileName = ""

class AddViewController: UIViewController,UIPickerViewDelegate,UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return imageFileName.count
    }
    /*
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return itemsImageFile[row]
    }
     */
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let imageView = UIImageView(image: imageArray[row])
        imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 150)
        
        return imageView
    }
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        imgView.image = imageArray[row]
        fileName = imageFileName[row]

    }
    
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return CGFloat(80)
    }
    	
    @IBOutlet var tfAddItem: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for i in 0 ..< MAX_ARRAY_NUM {
            let image = UIImage(named: imageFileName[i])
            imageArray.append(image!)
        }
        imgView.image = imageArray[0]
        fileName = imageFileName[0]
    }
    
    @IBAction func btnAddItem(_ sender: UIButton) {
        items.append(tfAddItem.text!)
        itemsImageFile.append(fileName)
        tfAddItem.text="" // 텍스트필드의 내용을 지운다.
        _ = navigationController?.popViewController(animated: true) // 내비게이션의 루트뷰로 돌아간다.
        // 근데 여기 이것만으로는 이전뷰가 업데이트가 안되서 뷰윌어피어를 테이블 뷰 컨트롤러에 추가한다.
    }
    
    @IBOutlet var imgView: UIImageView!
    @IBOutlet var imgPicker: UIPickerView!
    
    
    /*
    // 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.
    }
    */

}

 

//
//  TableViewController.swift
//  Table
//
//  Created by Hamlit Jason on 2021/02/25.
//

import UIKit

    var items = ["책 구매", "철수와 약속", "스터디 준비하기"] // 여기서 또 하나의 중요한 개념!! 다른 스위프트 파일에서도 참조하려면 클래스 밖에다가 선언해두어야 한다.
    var itemsImageFile = ["cart.png","clock.png","pencil.png"]

class TableViewController: UITableViewController {

    @IBOutlet var tvListView: UITableView!
    
 
    /* 참고
     뷰 디드로드 - 뷰가 로드 되었을 떄, 즉, 뷰가 생성될 때 한번만 호출된다.
     뷰 윌어피어 - 뷰가 노출될 준비가 끝났을 때 ,뷰가 노출될 때마다
     뷰 디드어피어 - 뷰가 완전히 보인 후 호출되는 함수, 뷰가 완전히 보인 후 호출된다.
     */
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for i in itemsImageFile {
            let image = UIImage(named: i)
            imageArray.append(image)
        }
        

        // 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.leftBarButtonItem = self.editButtonItem // 메인 스토리보드에 따로 추가하지 않아도 된다. 왼쪽 바버튼 아이템 사용하는 코드이다.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        tvListView.reloadData() // 테이블 뷰를 다시 불러온다. 즉, 테이블뷰에 변경사항이 있으면 반영한다.
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1 //보통은 테이블안에 섹션이 한개이므로 일단 1로한다.
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return items.count // 섹션당 열의 수는 아이템의 개수이므로 아이템의 갯수를 리턴한다.
    }

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        cell.textLabel?.text = items[(indexPath as NSIndexPath).row]
        cell.imageView?.image = UIImage(named: itemsImageFile[(indexPath as NSIndexPath).row])
        // Configure the cell...

        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
            items.remove(at: (indexPath as NSIndexPath).row)
            itemsImageFile.remove(at: (indexPath as NSIndexPath).row)
            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 func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
        return "삭제" // 왼쪽으로 밀었을때 딜리트를 한글로 삭제라고 뜨게 만드는 코드
    }

    
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
        // 목록을 드래그하여 위치를 바꾸는 함수이다.
        
        let itemToMove = items[(fromIndexPath as NSIndexPath).row] // 이동할 아이템의 위치
        let itemImageToMove = itemsImageFile[(fromIndexPath as NSIndexPath).row] // 이동할 아이템의 이미지
        items.remove(at: (fromIndexPath as NSIndexPath).row) // 이동할 아이템을 삭제 - 이때!!! 뒤의 아이템의 인덱스는 재정렬된다.
        itemsImageFile.remove(at: (fromIndexPath as NSIndexPath).row) // 이동할 이미지 삭제 - 이때!!! 뒤의 이미지의 인덱스는 재정렬된다.
        items.insert(itemToMove, at: (to as NSIndexPath).row) // 삭제된 아이템을 삽입 - 이떄!! 삽입 후 인덱스는 재정렬된다.
        itemsImageFile.insert(itemImageToMove, at: (to as NSIndexPath).row) // 삭제된 이미지 삽입 - 이때!! 삽입 후 인덱스는 재정렬된다.
        
        
    }
    

    /*
    // 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.
        NSLog("asd")
        if segue.identifier == "sgDetail" {
            let cell = sender as! UITableViewCell // 센더가 any 타입이라서 캐스팅해서 cell을 선언하고
            let indexPath = self.tvListView.indexPath(for: cell) //
            let detailView = segue.destination as! DetailViewController
            detailView.receiveItem(items[((indexPath! as NSIndexPath).row)])
        }
    }

}
	

'Archive > Doit 아이폰 앱(입문)' 카테고리의 다른 글

Navigation - 코드리뷰  (0) 2021.03.02
Tab - 코드리뷰 (탭바 컨트롤러)  (0) 2021.03.02
PageControl - 코드리뷰  (0) 2021.03.02
Map - 코드리뷰(맵뷰)  (0) 2021.03.02
Web - 코드리뷰(웹뷰)  (0) 2021.03.02