Uikit으로 돌아왔습니다.
이번에는 라이브러리를 사용하지 않고 CustomCalendar를 구현해보도록 하겠습니다.
1) 최상단에 있는 View를 먼저 구현해보겠습니다.
최상단은 button, title, button button으로 구성되어있습니다.
class CustomCalendarViewController: UIViewController {
// MARK: - Properties
// MARK: - 년, 월 ( 메인 타이틀 )
var titleLabel: UILabel = {
let title = UILabel()
title.font = UIFont.systemFont(ofSize: 15, weight: .semibold)
title.text = "2023년 01월"
title.textColor = .label
return title
}()
// MARK: - 이전 달, 다음달로 이동 버튼
var previousButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "chevron.left"), for: .normal)
button.setTitleColor(.label, for: .normal)
return button
}()
var nextButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(systemName: "chevron.right"), for: .normal)
button.setTitleColor(.label, for: .normal)
return button
}()
// MARK: - today 버튼
var todayButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Today", for: .normal)
button.backgroundColor = .black
button.tintColor = .white
button.layer.cornerRadius = 8
button.clipsToBounds = true
return button
}()
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configure()
}
func configure() {
configureTitleLabel()
configurePreviousButton()
configureNextButton()
configureTodayButton()
configureStackView()
configureCollectionView()
}
// MARK: - Title 레이아웃
func configureTitleLabel() {
view.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
}
func configurePreviousButton() {
view.addSubview(previousButton)
previousButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
previousButton.trailingAnchor.constraint(equalTo: titleLabel.leadingAnchor, constant: -10),
previousButton.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor),
previousButton.heightAnchor.constraint(equalToConstant: 44),
previousButton.widthAnchor.constraint(equalToConstant: 44)
])
}
func configureNextButton() {
view.addSubview(nextButton)
nextButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
nextButton.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 10),
nextButton.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor),
nextButton.heightAnchor.constraint(equalToConstant: 44),
nextButton.widthAnchor.constraint(equalToConstant: 44)
])
}
func configureTodayButton() {
view.addSubview(todayButton)
todayButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
todayButton.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor),
todayButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10),
todayButton.widthAnchor.constraint(equalToConstant: 70)
])
}
func configureStackView() {
}
func configureCollectionView() {
}
}
인스턴스를 클로저를 활용하여 생성해주고 상단의 부분의 레이아웃을 맞추면 됩니다.
configure()안에 함수를 넣어서 정리했습니다.
참 쉽죠?
2) 그 아래 요일들을 만들어줍니다
// MARK: - 요일 Label
var monLabel: UILabel = {
let title = UILabel()
title.text = "월"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var tusLabel: UILabel = {
let title = UILabel()
title.text = "화"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var wedLabel: UILabel = {
let title = UILabel()
title.text = "수"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var thsLabel: UILabel = {
let title = UILabel()
title.text = "목"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var friLabel: UILabel = {
let title = UILabel()
title.text = "금"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var satLabel: UILabel = {
let title = UILabel()
title.text = "토"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
var sunLabel: UILabel = {
let title = UILabel()
title.text = "일"
title.textAlignment = .center
title.font = UIFont.systemFont(ofSize: 12)
return title
}()
codebase의 장점이 여기서 들어납니다... 바로 개발자들에게 뗄래야 뗄 수 없는 복붙...

3) Label들을 하나씩 레이아웃 맞추는 것보다 StackView를 활용해서 맞춰줍니다.
// MARK: - StackView
lazy var weekStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [sunLabel, monLabel, tusLabel, wedLabel, thsLabel, friLabel, satLabel])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
return stackView
}()
자 여기서 보면 var 앞에 lazy가 붙었는데 왜 붙었을까요?
lazy를 붙이면 장점이 있는데, 자세한건 추후에 포스팅 하겠습니다... 요게 MZ밀당 맞나요? ㅎㅎ
쉽게 말씀드리면 순서에 차이를 둔다 고 보시면 됩니다.
메모리가 호출되면 그때 값을 초기화시킵니다.
그냥 var로 선언하고 StackView를 만들게 되면 비어있는 StackView와
Label가 동시에 올라가기 때문에 Error가 발생합니다.
4) 자 이렇게 StackView까지 만들었으면 레이아웃을 잡아 줍니다.
func configureStackView() {
view.addSubview(weekStackView)
weekStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
weekStackView.leadingAnchor
weekStackView.topAnchor
weekStackView.trailingAnchor
])
}
전 이렇게 먼저 앵커를 걸어둘곳을 먼저 생각하고 나머지를 완성시킵니다.
제 개인취향이니 존중해주시와요 ㅠ
func configureStackView() {
view.addSubview(weekStackView)
weekStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
weekStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 10),
weekStackView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 40),
weekStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -10)
])
}
현재까지 완성 사진입니다. 흠.. 나쁘지 않네요! 좋네요
그럼 여기서 끊고 다음에 또 만나요! 모두 화이팅 하세요!
참고 블로그
[iOS] Calendar 구조체로 달력 구현하기 (2) - 달력 뷰 구성하기
달력 뷰 미리 보기 Calendar 구조체도 알아봤으니 이제 달력 구현을 위하여 뷰를 구성해 보겠습니다. 위의 사진과 같은 심플한 달력을 만들 겁니다. 각각 뭐하는 친구들인지 설명도 적어드릴게요!
boreum.tistory.com
'Swift' 카테고리의 다른 글
iOS Custom Calendar 구현하기 3 (2) | 2023.04.18 |
---|---|
iOS Custom Calendar 구현하기2 (0) | 2023.04.17 |
어서와 SwiftUI @FetchRequest는 처음이지? (0) | 2023.03.23 |
SwiftUI @AppStorage 심화편 (0) | 2023.03.22 |
SwiftUI OpenAPI 적용시키기 (0) | 2023.02.14 |