본문 바로가기

iOS/STUDY

[iOS] UITableView

Tabel: Table view, data source, delegate

 

인터페이스 빌더

  1. Table view 넣기
  2. Table cell 넣기
  3. @IBOutlet UITableView 연결하기
  4. 스토리보드에서 dataSource, delegate를 View Controller 에 연결하기

코드 (4번)

self.tableView.delegate = self
self.tableView.dataSource = self

 

필수구현

  • numberOfRowsInSecion: 각 row의 행이 몇개인지
  • cellForRowAt: 각 cell에 들어갈 내용
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
        return korean.count
    case 1:
        return english.count
    default:
    	return 0
    }
}
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: indexPath)
        
    let text: String = indexPath.section == 0 ? korean[indexPath.row] : english[indexPath.row]
        
    cell.textLabel?.text = text
    
    return cell
}

 

optional 구현 (다른 것도 많음!)

  • numberOfSections: section 의 갯수
  • titleForGeaderInSection: 각 section에 header title (이름) 달기
func numberOfSections(in tableView: UITableView) -> Int {
    return 2
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return section == 0 ? "한글" : "영어"
}

iOS 14.4 기준 테이블 모양

Cell Style: Basic

Table View Style: Grouped

 

 

 

데이터를 동적으로 추가하기

 

새로운 배열 선언

var dates: [Date] = []

 

버튼 클릭시 데이터 추가

@IBAction func touchUpAddButton(_ sender: UIButton) {
    dates.append(Date())
    // 전체의 데이터를 다시 불러옴 - 비효율적
    // self.tableView.reloadData()
    self.tableView.reloadSections(IndexSet(2...2), with: UITableView.RowAnimation.automatic)
}

- reloadDate() 는 전체 데이터를 불러오기 때문에 비효율적이다.

- 애니메이션과 섹션만 불러오려면 reloadSections() 을 사용하자.

 

나머지 위의 함수에서 선언한 부분들을 알맞게 수정해주면 된다.

 

 

 

셀 커스터마이징

셀 안에 라벨 두개를 넣어서 왼쪽 라벨에는 날짜, 오른쪽 라벨에는 시간을 넣어서 커스텀해보자.

오토레이아웃 맞추면 자동으로 셀 안에 맞춰진다.

Style: Custom

Identifier: customCell (직접설정!)

 

커스텀으로 셀을 새로 구성해야하기 때문에 새로운 Cocoa touch 파일을 만들어준다.

만들어줄때 Subclass를 UITableViewCell 로 설정해준다.

 

셀 안에 left label, right label을 만들어주고,

//
//  CustomTableViewCell.swift
//  TableView
//

import UIKit

class CustomTableViewCell: UITableViewCell {
    
    @IBOutlet var leftLabel: UILabel!
    @IBOutlet var rightLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

스토리보드에서 아까 만들어 둔 customCell을 클릭한 후에 Custom Class에

우리가 만든 CustomTableViewCell으로 설정한다.

왼쪽 뷰 컨트롤러 씬에서 customCell에 우클릭을하면 IBOutlet을 연결할 수 있다.

 

원래의 뷰컨트롤러 파일로 돌아와서 tableView에 cell의 내용을 넣는 부분을 바꿔주어야한다.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section < 2 {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for: indexPath)
        let text: String = indexPath.section == 0 ? korean[indexPath.row] : english[indexPath.row]
        cell.textLabel?.text = text
        return cell
    }
    else {
        // 강제 캐스팅
        let cell: CustomTableViewCell = tableView.dequeueReusableCell(withIdentifier: self.customCellIdentifier, for: indexPath) as! CustomTableViewCell
            
        cell.leftLabel.text = dateFormatter.string(from: self.dates[indexPath.row])
        cell.rightLabel.text = dateFormatter.string(from: self.dates[indexPath.row])
            
        return cell
    }
}

else 부분이 우리가 추가해야 할 셀의 내용을 넣는 부분이다.

일반 UITableViewCell의 인스턴스를 가져오는 메서드를 사용했기 때문에 타입캐스팅을 해줘야한다. (as!)

여기서는 강제캐스팅을 사용했다고 하는데 강제캐스팅 말고 사용하는 방법은 나중에 알아보라ㅏ...

 

guard let cell: CustomTableViewCell = tableView.dequeReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell else {
	preconditionFailure("테이블 뷰 셀 가져오기 실패")
}

강제캐스팅이긴한데 guard let 으로 묶으면 안전하게 실행가능

흠 

 

재ㅣ미따