2021. 11. 15. 19:55ㆍUIKit, SwiftUI, H.I.G
1️⃣ 오늘 만들어줄 화면은?
흔히, 내가 '도르륵'이라고 부르는 녀석을 만들어줄거다.
이 녀석의 정식 명칭은 UIPickerView이다.
날짜와 시간을 지정할 때는 Apple에서 기본으로 제공해주는 Date Picker를 사용하게 되는데, 안에 들어가는 내용을 직접 커스텀하기 위해서는 그냥 "PickerView"를 사용해야 한다.
사용 방법은 UITableView와 굉장히 유사하기 때문에 아마 쉽게 배울 수 있을거라 생각한다.
일단, 항상 그랬던 것처럼 공식문서부터 읽어보자.
✍🏻 애플 공식문서 보러가기
2️⃣ 기본세팅
여기서는 코드로 추가해줬지만, 스토리보드에 그냥 끌어넣기해도 된다.
일단, 여기서 주목해야될 부분은 2곳인데,
첫 번째, 피커 뷰 안에다가 넣을 내용을 리스트 변수로 선언해서 넣어두는 부분이다.
두 번째, 테이블 뷰처럼 delegate와 dataSource를 선언해둔 부분이다. delgate와 dataSource를 지정했으니, 그 세부내용을 구현해주러 가보자.
// 피커 뷰에 들어갈 내용 리스트
var pickerList = ["가가가가", "나나나나", "다다다다", "라라라라", "마마마마", "바바바바", "사사사사"]
// 피커 뷰 추가
private let groupPickerView: UIPickerView = {
let pickerView = UIPickerView()
return pickerView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
// 테이블 뷰처럼 피커 뷰도 delegate, datasource 넣어줘야 한다!
groupPickerView.dataSource = self
groupPickerView.delegate = self
}
// UI 세팅 작업
private func setupUI() {
view.addSubview(completeButton)
view.addSubview(groupPickerView)
setupLayout()
}
3️⃣ UIPickerViewDataSource
테이블 뷰처럼 2개의 메서드를 필수로 구현해줘야 한다.
하나는 피커 뷰 내부의 컴포넌트 개수를 지정하는 numberOfComponents 메서드이고,
또 다른 하나는 피커뷰 컴포넌트의 개수를 지정하는 numberOfRowsInComponent 메서드이다.
/* 필수 */
// 도르륵을 몇개 넣을지 -> 년도, 월, 일을 선택하려면 3개를 넣으면 되겠다.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// pickerView 안에 들어갈 항목의 개수를 반환 -> list를 안에 넣은다 했으니, list.count를 넣어줬다.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerList.count
}
4️⃣ UIPickerViewDelegate
필수는 아니지만, 사용하는 피커뷰의 세부 내용을 Delegate에 구현해줄 수도 있다.
높이, 너비, 타이틀 색 지정, 액션 같은 세부 내용이 있으니 이는 아래 코드와 주석에 써있는 내용을 참고하여 사용하도록 하자.
// 피커 뷰 행의 높이
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 44
}
// 피커 뷰 행의 넓이
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return 200
}
// 피커 뷰에서 특정 위치(row)를 가리킬 때, 그 위치에 해당하는 문자열을 반환
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerList[row]
}
// row 타이틀(글씨)에 적용
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
return NSAttributedString(string: pickerList[row], attributes: attributes)
}
// row 뷰에서 적용
func pickerView(UIPickerView, viewForRow: Int, forComponent: Int, reusing: UIView?) -> UIView {
return UIView
}
// 피커 뷰에서 특정 위치(row)가 선택되었을 때, 할 행동을 정의
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
5️⃣ 추가로 특정 row 선택시 글씨 색상과 폰트 바꿔주는 방법
이 중에서 특히, 위에서 나온 attributedTitleForRow delegate 메서드를 활용해서 특정 row가 선택되면 글씨의 색상과 폰트를 바꿔주는 방법에 대해서만 따로 알아보겠다.
inComponent가 0인 지점의 color와 font를 변경해주는 방식인데,
특정 위치에 row가 놓아지면, reloadComponet를 이용해서 componet를 다시 불러오게 된다. 그 후, 변경해주는 방식!
var selectedRow: Int {
return groupPickerView.selectedRow(inComponent: 0)
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadComponent(component)
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
var color = UIColor.gray
var font = UIFont.systemFont(ofSize: 16)
if row == selectedRow {
color = UIColor(red: 246/255, green: 112/255, blue: 102/255, alpha: 1.0)
font = UIFont.systemFont(ofSize: 16, weight: .bold)
}
let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key(rawValue: NSAttributedString.Key.foregroundColor.rawValue): color,
NSAttributedString.Key(rawValue: NSAttributedString.Key.font.rawValue): font
]
return NSAttributedString(string: pickerList[row], attributes: attributes)
}
💡Reference
'UIKit, SwiftUI, H.I.G' 카테고리의 다른 글
[UITapGestureRecognizer] UILabel을 클릭가능하도록 만들기 (0) | 2021.12.17 |
---|---|
[iOS] iOS 앱 다크모드 대응기: 시스템을 무시하고 앱 자체적으로 다크모드를 적용하기 (0) | 2021.12.17 |
[UITapGestureRecognizer] UIGestureRecognizer 2탄 - Tap Gesture로 키보드 내리기 + 모달창 끄기 (0) | 2021.11.06 |
[UIPanGestureRecognizer] UIGestureRecognizer 1탄 - 아래로 드래그해서 모달창 dismiss하는 방법 (0) | 2021.10.31 |
[CAGradientLayer] UIView setGradient - 그라데이션 사용하기 (0) | 2021.10.23 |