Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Xcode
- JSONSerialization
- pbxgroup
- parse
- 위클리챌린지
- JSONParser
- programmers
- CustomCode
- 2018 KAKAO BLIND RECRUITMENT
- SwiftGen
- 프로그래머스
- UITableView
- 정보처리기사 실기 요약본
- Decodable
- storybaord
- 정보처리기사 실기
- swift
- Pod
- 정보처리기사
- cocoapods
- JSON
- PageViewController
- pbxfilesystemsynchronizedrootgroup
- Custom PageViewController
- 티스토리챌린지
- IOS
- Codable
- issecuretextentry
- RealmSwift
- dynamic height
Archives
- Today
- Total
iOS 개발일기
[Swift] Custom PageViewController 본문
기존 PageViewController를 사용한 방법이 아닌
UICollectionView를 이용하여 PageViewController를 구현해보았습니다.
import UIKit
class PageViewController: UIViewController {
var indicatorConstraint: NSLayoutConstraint?
var indicatorView: UIView!
var naviCollection: UICollectionView!
var pageCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
setupControls()
setupLayout()
initData()
}
private func setupControls() {
indicatorView = UIView()
indicatorView.backgroundColor = .black
naviCollection = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.showsHorizontalScrollIndicator = false
cv.delegate = self
cv.dataSource = self
cv.register(NaviCell.self, forCellWithReuseIdentifier: NaviCell.cellId)
return cv
}()
pageCollection = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.isPagingEnabled = true
cv.showsHorizontalScrollIndicator = false
cv.delegate = self
cv.dataSource = self
cv.register(PageCell.self, forCellWithReuseIdentifier: PageCell.cellId)
return cv
}()
}
private func setupLayout() {
view.backgroundColor = .white
view.addSubview(naviCollection)
view.addSubview(indicatorView)
view.addSubview(pageCollection)
naviCollection.translatesAutoresizingMaskIntoConstraints = false
indicatorView.translatesAutoresizingMaskIntoConstraints = false
pageCollection.translatesAutoresizingMaskIntoConstraints = false
naviCollection.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
naviCollection.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
naviCollection.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
naviCollection.heightAnchor.constraint(equalToConstant: 60).isActive = true
indicatorView.topAnchor.constraint(equalTo: naviCollection.bottomAnchor).isActive = true
indicatorView.widthAnchor.constraint(equalToConstant: view.frame.width / 4).isActive = true
indicatorView.heightAnchor.constraint(equalToConstant: 3).isActive = true
indicatorConstraint = indicatorView.leftAnchor.constraint(equalTo: view.leftAnchor)
indicatorConstraint?.isActive = true
pageCollection.topAnchor.constraint(equalTo: indicatorView.bottomAnchor).isActive = true
pageCollection.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
pageCollection.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
pageCollection.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}
private func initData() {
let indexPath = IndexPath(item: 0, section: 0)
naviCollection.selectItem(at: indexPath, animated: false, scrollPosition: [])
}
}
extension PageViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch collectionView {
case naviCollection:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NaviCell.cellId, for: indexPath) as! NaviCell
cell.index = indexPath.item
return cell
case pageCollection:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PageCell.cellId, for: indexPath) as! PageCell
cell.index = indexPath.item
return cell
default:
return UICollectionViewCell()
}
}
func collectionView(_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath) {
guard collectionView == naviCollection else {return}
naviCollection.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
pageCollection.reloadData()
pageCollection.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
switch collectionView {
case naviCollection:
return CGSize(width: collectionView.frame.width / 4, height: 60)
case pageCollection:
return collectionView.frame.size
default:
return .zero
}
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
indicatorConstraint?.constant = scrollView.contentOffset.x / 4
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let item = Int(targetContentOffset.pointee.x / scrollView.frame.width)
let indexPath = IndexPath(item: item, section: 0)
naviCollection.selectItem(at: indexPath, animated: true, scrollPosition: [])
}
}
각 CollectionView에 사용되는 Cell입니다.
import UIKit
class NaviCell: UICollectionViewCell {
static let cellId = "NaviCellId"
var index: Int? {
willSet {
titleLabel.text = nil
}
didSet {
guard let index = index else {return}
titleLabel.text = String(index + 1) + "번 탭"
}
}
var titleLabel: UILabel!
override var isSelected: Bool {
didSet {
titleLabel.textColor = isSelected ? .black : .lightGray
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupControls()
setupLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupControls() {
titleLabel = {
let l = UILabel()
l.textAlignment = .center
l.textColor = .lightGray
l.font = .boldSystemFont(ofSize: 20)
return l
}()
}
private func setupLayout() {
addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
}
import UIKit
class PageCell: UICollectionViewCell {
static let cellId = "PageCellId"
var index: Int? {
willSet {
titleLabel.text = nil
}
didSet {
guard let index = index else {return}
titleLabel.text = String(index + 1) + "번 셀"
}
}
var titleLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
setupControls()
setupLayout()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupControls() {
titleLabel = {
let l = UILabel()
l.textColor = .black
l.textAlignment = .center
l.font = .boldSystemFont(ofSize: 40)
return l
}()
}
private func setupLayout() {
addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
}
참고
'iOS > Swift' 카테고리의 다른 글
[Swift] UITableView Dynamic Height (0) | 2024.12.26 |
---|---|
[Swift] 'didSelectItemAt' 함수가 호출되지 않는 이유 (2) | 2023.12.07 |
[Swift] JSONParser - JSONSerialization (0) | 2022.03.16 |
[Swift] JSONParser - Decodable(2) (0) | 2022.03.15 |
[Swift] JSONParser - Decodable(1) (0) | 2022.03.14 |