티스토리 뷰

iOS

[iOS] UITableView 톺아보기 - 2

국산 앨런 2019. 8. 1. 10:27

이론을 어느 정도 톺아 보았으니

 

테이블 뷰를 이리 저리 마구 잡이로 가지고 놀아 보겠습니다.

 

포켓몬 도감? 만들기

 

... 네

 

도감을 만들어 보려 합니다 ㅎㅅㅎ

 

구성

  • UITableView
  • 셀 추가 버튼 3개 (오박사, 메타몽, 꼬부기)
  • DoctorCell (오박사), MonsterCell (메타몽, 꼬부기)

동작

  • 버튼에 따라 서로 다른 Cell이 추가됩니다
  • editing 모드로 cell 삭제를 합니다

 

먼저 사용될 UIViewController에 UITableView를 뷰전체 사이즈로 추가합니다.

 

UITableViewCell 하나를 추가한 뒤 Style을 Basic으로, Identifier를 "DoctorCell"로 지정해줍니다.

 

UITableView안에 Stack뷰를 하나 추가한 뒤 3개의 버튼을 추가해줍니다. (StackView Distribution = 'Fill Equally')

 

3개의 버튼에 대해서 Identity inspector에 있는 Restoration Id를 각각 addDoctor, addMetamong, addTurtle 으로 지정해줍니다.

 

이제 MonsterCell 클래스를 생성할 건데

 

xib를 이용해서 storyboard 외부에서 Cell을 가져와보겠습니다.

 

 

New File -> Cocoa Touch Class -> UITableViewCell (also create XIB file) -> MonsterCell.swift, MonsterCell.xib

 

 

MonterCell.xib로 들어가서 Class를 지정해주고, Restoration ID를 클래스명으로 지정합니다. 

 

뷰컨에서 찾아갈 명칭이니 잘 확인해주세요~

 

UIImageView와 UILabel은 기존 StoryBoard에서 하던 방식대로 MonterCell에  @IBOutlet으로 참조 시켜주세요.

 

//ViewController.swift

import UIKit

class ViewController: UIViewController{

    @IBOutlet weak var tableView: UITableView!
    
    //각 Cell에 대한 Data List
    private var doctersWords: [String] = []
    private var monsters: [Monster] = []
    //이미지 리소스, 셀 클래스 이름
    private let metamongImageSrc = UIImage(named: "metamong")
    private let turtleImageSrc = UIImage(named: "turtle")
    private let doctorImageSrc = UIImage(named: "doctor")
    private let MonsterCellString = String(describing: MonsterCell.self)
    
    //3개의 버튼에 대한 Action
    //버튼 클릭시 특정 section에 행 삽입
    @IBAction func buttonAction(_ sender: UIButton) {
        switch sender.restorationIdentifier {
            case "addMetamong":
                monsters.append(Monster(imageSrc: metamongImageSrc!, name: "메타몽"))
                tableView.reloadSections(IndexSet(1...1), with: .automatic)
            case "addTurtle":
                monsters.append(Monster(imageSrc: turtleImageSrc!, name: "꼬부ㄱ..몽"))
                tableView.reloadSections(IndexSet(1...1), with: .automatic)
            default://doctor
                doctersWords.append(getDoctorsWord())
                tableView.reloadSections(IndexSet(0...0), with: .automatic)
        }
    }
    //오박사님의 말씀
    private func getDoctorsWord() -> String{
        //현재시간 가져오기
        let date = Date()
        let calendar = Calendar.current
        let hour = calendar.component(.hour, from: date)
        let minutes = calendar.component(.minute, from: date)
        
        return "벌써 \(hour)시 \(minutes)분 이군! 이런이런 늦었구만"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //UITableViewDelegate, UITalbeViewDataSource 등록
        tableView.delegate = self
        tableView.dataSource = self
        //외부 Cell 등록 -> 이 작업이 있어야 xib 파일을 가져다 쓸 수 있습니다.
        tableView.register(UINib(nibName: MonsterCellString, bundle: nil), forCellReuseIdentifier: MonsterCellString)
    }
}

 

buttonAction 부분은 생성된 3개의 버튼에 대한 Action을 연결한 부분인데요, 

 

서로 같은 액션을 참조하되 storyboard에서 지정한 restorationIdentifier를 통해서 구분합니다.

 

버튼을 누를때마다 버튼에 따른 데이터를 그에 맞는 List에 추가합니다.

 

그리고 테이블 뷰를 리로드 시켜서 업데이트된 데이터를 테이블뷰에 반영시켜줍니다.

 

.reloadData() 는 UITableView 전체를 리로드하기 때문에 특정 섹션만 리로드 시키기 위해 .reloadSections(...) 를 사용합니다

 

어...음.. 주석 보시면서 차근차근 따라와주세요 ^---^

 

//ViewController.swift

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    //number of sections = 2 : doctor, monster
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    //section에 따른 행 높이 지정
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.section == 0{
            return 70
        }else{
            return 140
        }
    }
    //section에 따른 행(Data) 갯수 지정
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 1 {
            return monsters.count
        }
        else{
            return doctersWords.count
        }
    }
    //section에 따른 cell 지정
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0 { //doctor
            guard let cell = tableView.dequeueReusableCell(withIdentifier: "DoctorCell") else {
                    return UITableViewCell()
            }
            
            cell.textLabel?.text = doctersWords[indexPath.row]
            return cell
        }
        else{  //monster
            guard let cell: MonsterCell = tableView.dequeueReusableCell(withIdentifier: MonsterCellString, for: indexPath) as? MonsterCell else{
                    return UITableViewCell()
            }
            
            let monster = monsters[indexPath.row]
            cell.monsterImageView.image = monster.imageSrc
            cell.nameLabel.text = monster.name
            return cell
        }
    }
}

 

DoctorCell은 Basic으로 지정했기에 기본적으로 textLabel과 imageView를 가지고 있습니다.

 

UITableView의 테이블과 셀에 대한 셋팅이 마무리 되었구요

 

//Monster.swift

import UIKit

struct Monster {
    let imageSrc: UIImage
    let name: String
}

 

코드가 마무리 되었습니다.

 

 

으우어어ㅗㅋ럭ㅇㄹ럭

 

 

 

 

참고 : https://www.edwith.org/boostcourse-ios/lecture/16889/

댓글
공지사항