https://developer.apple.com/documentation/uikit/uitableview
UITableView | Apple Developer Documentation
A view that presents data using rows in a single column.
developer.apple.com
https://developer.apple.com/documentation/uikit/uitableviewcell
UITableViewCell | Apple Developer Documentation
The visual representation of a single row in a table view.
developer.apple.com
테이블 뷰 변수 선언, 제약조건, 뷰 등록 ->
테이블 셀에 들어갈 데이터 뼈대 및 뼈대를 통해 얻은 데이터를 관리할 모델 생성
-> 테이블 셀 안에 들어갈 UI 설정 -> 테이블뷰와 테이블 셀 연결 및 데이터 전달
ViewController.swift
import UIKit
class ViewController: UIViewController {
// 11. DataManager 클래스의 인스턴스 생성
var fruitDataManager = DataManager()
// 12. 생선된 fruitDataManager 인스턴스를 통해 받아온 데이터를 담을 배열 선언
var fruitArray: [Fruit] = []
// 1. 테이블 뷰 변수 선언
private let tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
// 3. 뷰에 tableView 올림
view.addSubview(tableView)
// 4. 제약 조건 올림 (이 뒤로 Model 폴더 명 내에 Fruit, DataManager 파일 생성)
tableViewConfigureConstraints()
// 16. DataManager에게 데이터 생성을 요청 및 받아온 데이터를 배열에 할당
fruitDataManager.makeFruitDatasArray()
fruitArray = fruitDataManager.getFruitDatasArray()
// 17. 테이블셀 높이 설정
tableView.rowHeight = 120
// 14. dataSource의 대리자 선언
tableView.dataSource = self
// 15. 테이블 뷰 등록
tableView.register(ContentsTableViewCell.self, forCellReuseIdentifier: "cell")
}
// 2. 테이블 뷰 관련 제약 조건 설정
private func tableViewConfigureConstraints() {
let tableViewConstraints = [
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
]
NSLayoutConstraint.activate(tableViewConstraints)
}
}
// 13. 전달 받은 데이터를 통해 테이블을 구성하기 위해 UITableViewDataSource 프로토콜 채택
extension ViewController: UITableViewDataSource {
// 행의 수 설정
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruitArray.count
}
// 데이터를 테이블 셀에 각각 설정
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ContentsTableViewCell
cell.fruitImageView.image = fruitArray[indexPath.row].fruitImage
cell.fruitNameLabel.text = fruitArray[indexPath.row].fruitName
cell.fruitDescriptionLabel.text = fruitArray[indexPath.row].fruitDescription
cell.selectionStyle = .none
return cell
}
}
여기서 중요한 부분은 대리자 선언및 테이블뷰 등록
Model 폴더 내에 두 데이터 관련 파일 생성
Fruit 파일 내에 아래 코드 작성
// 5. 데이터 모델 구조 생성 (이를 통해 데이터 뼈대 생성 -> DataManager 파일로 넘어갈 것)
struct Fruit {
var fruitImage: UIImage?
var fruitName: String
var fruitDescription: String
}
DataManager 파일 내에 아래 코드 작성
// 6. Fruit의 데이터 뼈대를 기준으로 데이터 관리 모델 생성
class DataManager {
private var fruitDataArray: [Fruit] = []
// 7. 데이터를 저장할 배열을 생성 하고,
// 이를 통해 CRUD 할 함수를 따로 생성 할 것 (Views 폴더 내에 ContentsTableViewCell 파일 생성)
func makeFruitDatasArray() {
fruitDataArray = [
Fruit(fruitImage: UIImage(named: "avocado"), fruitName: "avocado", fruitDescription: "과일의 일종으로 원산지는 멕시코를 비롯한 중남미 지역. 멕시코에서는 연중 재배 및 수출이 가능하며, 현지 도매시장에서는 가격이 매우 저렴한 편이다."),
Fruit(fruitImage: UIImage(named: "blueberry"), fruitName: "blueberry", fruitDescription: "북아메리카를 비롯한 북반구 전역에 분포하는 식물 및 열매. 이름과 달리 딸기, 라즈베리, 블랙베리 등의 베리류와는 전혀 관계가 없는 진달래과 식물[1]이다. 꽃말은 현명과 친절이다."),
Fruit(fruitImage: UIImage(named: "cherry"), fruitName: "cherry", fruitDescription: "벚나무의 열매. 순우리말로는 버찌라고 한다. 다만 보통 한국에서 접하는 사진의 서양버찌는 체리라 부르고 동양버찌는 버찌라고 별개로 부르는 편이 많다."),
Fruit(fruitImage: UIImage(named: "avocado"), fruitName: "avocado", fruitDescription: "과일의 일종으로 원산지는 멕시코를 비롯한 중남미 지역. 멕시코에서는 연중 재배 및 수출이 가능하며, 현지 도매시장에서는 가격이 매우 저렴한 편이다."),
Fruit(fruitImage: UIImage(named: "blueberry"), fruitName: "blueberry", fruitDescription: "북아메리카를 비롯한 북반구 전역에 분포하는 식물 및 열매. 이름과 달리 딸기, 라즈베리, 블랙베리 등의 베리류와는 전혀 관계가 없는 진달래과 식물[1]이다. 꽃말은 현명과 친절이다."),
Fruit(fruitImage: UIImage(named: "cherry"), fruitName: "cherry", fruitDescription: "벚나무의 열매. 순우리말로는 버찌라고 한다. 다만 보통 한국에서 접하는 사진의 서양버찌는 체리라 부르고 동양버찌는 버찌라고 별개로 부르는 편이 많다."),
Fruit(fruitImage: UIImage(named: "avocado"), fruitName: "avocado", fruitDescription: "과일의 일종으로 원산지는 멕시코를 비롯한 중남미 지역. 멕시코에서는 연중 재배 및 수출이 가능하며, 현지 도매시장에서는 가격이 매우 저렴한 편이다."),
Fruit(fruitImage: UIImage(named: "blueberry"), fruitName: "blueberry", fruitDescription: "북아메리카를 비롯한 북반구 전역에 분포하는 식물 및 열매. 이름과 달리 딸기, 라즈베리, 블랙베리 등의 베리류와는 전혀 관계가 없는 진달래과 식물[1]이다. 꽃말은 현명과 친절이다."),
Fruit(fruitImage: UIImage(named: "cherry"), fruitName: "cherry", fruitDescription: "벚나무의 열매. 순우리말로는 버찌라고 한다. 다만 보통 한국에서 접하는 사진의 서양버찌는 체리라 부르고 동양버찌는 버찌라고 별개로 부르는 편이 많다.")
]
}
func getFruitDatasArray() -> [Fruit] {
return fruitDataArray
}
}
테이블 셀 관련 파일 생성
생성한 ContentsTableViewCell 파일 내 아래 코드 작성
import UIKit
class ContentsTableViewCell: UITableViewCell {
// 8. 테이블 셀 안에 들어갈 라벨과 이미지 구현
let fruitImageView: UIImageView = {
let imageView = UIImageView(image: UIImage.banana)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.layer.masksToBounds = true
imageView.layer.cornerRadius = 5
return imageView
}()
let fruitNameLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "바나나"
label.font = .systemFont(ofSize: 22, weight: .bold)
label.textColor = .black
return label
}()
let fruitDescriptionLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .systemFont(ofSize: 15, weight: .regular)
label.textColor = .black
label.numberOfLines = 2
label.text = "바나나는 생강목 파초과 파초속에 속하는 외떡잎식물의 총칭으로, 흔히 열매만을 가리키기도 한다."
return label
}()
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 15
return stackView
}()
// 9. 테이블 셀에 필요한 내용을 업데이트
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(fruitImageView)
self.contentView.addSubview(stackView)
stackView.addArrangedSubview(fruitNameLabel)
stackView.addArrangedSubview(fruitDescriptionLabel)
configureConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// 10. 테이블 셀 안에 라벨과 이미지 관련 제약 조건 설정 (ViewController 파일로 넘어갈 것)
private func configureConstraints() {
let fruitImageViewConstraints = [
fruitImageView.heightAnchor.constraint(equalToConstant: 100),
fruitImageView.widthAnchor.constraint(equalToConstant: 100),
fruitImageView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10),
fruitImageView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10)
]
let fruitNameLabelConstraints = [
fruitNameLabel.heightAnchor.constraint(equalToConstant: 22)
]
let stackViewConstraints = [
stackView.leadingAnchor.constraint(equalTo: fruitImageView.trailingAnchor, constant: 10),
stackView.topAnchor.constraint(equalTo: fruitImageView.topAnchor, constant: 5),
stackView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10)
]
NSLayoutConstraint.activate(fruitImageViewConstraints)
NSLayoutConstraint.activate(fruitNameLabelConstraints)
NSLayoutConstraint.activate(stackViewConstraints)
}
}
다시 ViewController 파일로 돌아와서 아래 코드 작성
몇 가지 확인해봐야 하는 상황
왜 테이블뷰셀에서는 init 함수를 사용하는가?
여기다가 데이터를 생성 읽기 업데이트 쓰기를 네비게이션바를 통해 해볼 것
셀을 누르면 디테일 화면으로는 어떻게 넘어가는가?
'UIKIT' 카테고리의 다른 글
리소스 접근 권한 설정 (카메라, 앨범) (0) | 2024.01.25 |
---|---|
iOS 화면 표현 구조 (1) | 2024.01.22 |
네비게이션컨트롤러 및 네비게이션바 (0) | 2024.01.18 |
BMI 계산기 (화면 전환 및 데이터 전달) (0) | 2024.01.16 |
화면 이동과 데이터 전달 1편 (0) | 2024.01.14 |