본문 바로가기
💡 Today I Learned/개인 과제

[개인과제] 연락처 앱 만들기 1️⃣

by 솔비님 2024. 7. 16.

 

 

앱 개발 숙련주차 과제로 만들어야하는 연락처 앱

오늘은 1단계인 테이블뷰를 활용한 UI 만들기를 진행할 예정이다 :)

 

 


01.  테이블뷰(tableView) 세팅

테이블뷰 초반 세팅을 진행해 주었다

데이터를 입력 받은 다음 가져와야해서 CoreData와 Constrai

nts에 필수인 Snapkit도 넣어줌!

import UIKit
import CoreData
import SnapKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    //AppDelegate에서 생성한 NSPersistentContainer를 불러옴
    //Cannot find type 'NSPe~~ 오류 뜰 경우에는 import를 안 해준 것
    var container: NSPersistentContainer!
    private let tableView = UITableView()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        //appDelegate가 AppDelegate에 접근할 수 있도록 타입캐스팅
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        self.container = appDelegate.persistentContainer
        
        setUpTableView()
    }
    
    private func setUpTableViewDelegate() {
        tableView.delegate = self
        tableView.dataSource = self
    }
    
    private func setUpTableView() {
        setUpTableViewDelegate()
        view.addSubview(tableView)    
        
        //오토레이아웃 설정
        tableView.snp.makeConstraints {
            $0.edges.equalTo(view)
        }
        
        //테이블뷰 셀 등록
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
    }
    
    //테이블뷰 셀 개수
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6 // 추후 변경
    }
    
    //테이블뷰 셀이 필요할 때마다 해당 메서드를 호출한다(셀이 없다면 새로운 셀을 생성한다)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "Row \(indexPath.row)"
        return cell
    }
}

 

 

화면은 이렇게 나옴!

 

일단 테이블뷰 셀 내부에 사진, 이름, 연락처가 들어가야해서 셀 간격을 넓혀줘야할 필요가 있을 것 같고,

확인을 위해 임시로 넣어둔 view에 맞춰둔 오토레이아웃도 수정할 필요가 있어보인다

 

그 다음에 천천히 UI를 구성할 예정

 

 


02.  친구목록 타이틀 설정

테이블뷰 오토레이아웃 잡아주기 위해 친구목록 텍스트를 넣어주면 간격 잡아주기 편할 것 같아서

Label로 세팅했는데, title을 쓰면 더 간결한 코드 작성이 가능하다 해서 수정해 줬다!

 

간단한 코드 한 줄 넣는 것 만으로도 타이틀 UI가 아래와 같이 생성됨

self.title = "친구목록"

 

 


03.  테이블뷰(tableView) 오토레이아웃 설정

 

처음에 슈퍼뷰로부터 20 떨어지게 설정해 두었는데 레이아웃 변동이 없었다 ..

safeAreaLayoutGuide으로 설정하면 네이게이션바를 제외한 기준에서 레이아웃 설정이 된다고 해서 변경해 줌

 

 

Cell 간격 나눠주는 회색 밑줄때문에 레이아웃 설정이 잘못 됐나 싶어서 Hierarchy 확인해 봤는데

레이아웃 설정은 잘 되어있어서 일단 Cell 내부에 필요한 것들 다 집어넣고 확인해 보기로 했다

 


04.  테이블뷰 내부 UI 생성 & 레이아웃 설정

전화번호부에 기본적으로 필요한 이미지, 이름, 전화번호 생성을 위해 각각 imageView, Label 을 테이블뷰 cell 내에 넣어줘야한다

이때부터 코드가 길어지게 되어서 파일을 나누어 주었다

 

 

새로 생성한 TableViewCell에 cell 내부에 들어갈 UI 코드를 모두 넣어 주었다

imageView에 프레임사이즈를 주석처리한 이유는, 어짜피 레아이웃 잡을 때 사이즈를 넣어주어야하기 때문에 중복 적용할 필요가 없다

    let imgView = {
        let imgVw = UIImageView()
//        imgVw.frame.size = CGSize(width: 40, height: 40)
        imgVw.layer.cornerRadius = 25
        imgVw.layer.borderWidth = 2
        imgVw.clipsToBounds = true // 모서리가 둥글게 잘리도록 설정
        imgVw.layer.borderColor = UIColor.lightGray.cgColor
        return imgVw
    }()
    
    let nameLabel = {
        let nameLb = UILabel()
        nameLb.textAlignment = .center
        nameLb.textColor = .black
        nameLb.backgroundColor = .white
        nameLb.text = "김동남"
        nameLb.font = UIFont.systemFont(ofSize: 15)
        return nameLb
    }()
    
    let numberLabel = {
        let numLb = UILabel()
        numLb.textAlignment = .left
        numLb.textColor = .black
        numLb.backgroundColor = .white
        numLb.text = "010-0000-0000"
        numLb.font = UIFont.systemFont(ofSize: 15)
        return numLb
    }()

 

셀 초기화 시 호출되는 메서드도 넣어주고 에러코드도 넣어 주었다

제약조건을 잡아주기 위한 함수 configureUI()도 해당 코드에 추가해 주었다

    //셀 초기화 시 호출되는 메서드
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        configureUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("*T_T*")
    }

 

그리고 제약조건을 넣어주고, 아까 imageView에서 제외했던 프레임사이즈도 해당 부분에 잊지않고 넣어준다

아직도 offset, inset이 약간은 헷갈린다 ..

    private func configureUI() {
        [imgView, nameLabel, numberLabel].forEach {
            contentView.addSubview($0)
        }
        
        imgView.snp.makeConstraints {
            $0.leading.equalToSuperview().offset(10)
            $0.centerY.equalToSuperview()
            $0.width.height.equalTo(50) //사이즈 제약 조건 추가
        }
        
        nameLabel.snp.makeConstraints {
            $0.leading.equalTo(imgView.snp.trailing).offset(20)
            $0.centerY.equalToSuperview()
        }
        
        numberLabel.snp.makeConstraints {
            $0.trailing.equalToSuperview().offset(-10)
            $0.centerY.equalToSuperview()
        }

 


05.  뷰컨트롤러 테이블뷰에 연결해주기

뷰컨트롤러에서 만들어준 cell UI를 가져와서 사용할 수 있도록 코드를 짜주어야 한다

파일을 나눠서 관리하는 건 처음이라 여기저기 물어봐서 해결했다 (구조는 생소했지만 코드는 생각보다 간결했다)

 

viewDidLoad()에 테이블뷰를 재사용 할 수 있게 만들어주는 register 코드를 넣어주고,

forCellReuseIdentifier에 내가 생성한 cellUI class를 넣어준다

    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        //테이블뷰 셀을 재사용 할 수 있게 만들어주는 코드
        tableView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")

 

주석을 간단하게 달아놓았는데, 기본으로 제공되는 cell을 커스텀할 수 있게 내가 만든 cellUI로 변경해주는 코드

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //기본제공되는 cell을 TableViewCell로 변경해줌
        //tableView.register 갖다씀
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as? TableViewCell else {
            return UITableViewCell()
        }
        return cell
    }

 

여기까지 작성하고 실행한 모습인데..

라인 왼쪽이 잘리는 오류 발생

 

간단하게 한 줄 추가하는 것으로 해결완료! 💫

tableView.separatorInset.left = 0