Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GWL-6] 탭바 기록화면 UI구성 #66

Merged
merged 12 commits into from
Nov 20, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// CalendarCollectionViewCell.swift
// RecordFeature
//
// Created by 안종표 on 2023/11/18.
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import DesignSystem
import UIKit

// MARK: - CalendarCollectionViewCell

final class CalendarCollectionViewCell: UICollectionViewCell {
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = 1
stackView.alignment = .center
stackView.distribution = .fillEqually
stackView.axis = .vertical
return stackView
}()

let dayOfWeekLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .footnote)
label.text = "월"
label.textColor = DesignSystemColor.gray03
return label
}()

let dateLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body, with: .traitBold)
label.text = "16"
label.textColor = DesignSystemColor.gray03
return label
}()

override init(frame: CGRect) {
super.init(frame: frame)
}

@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("No Xib")
}

func configure(calendarInformation: CalendarInforamtion) {
configureUI()
dayOfWeekLabel.text = calendarInformation.dayOfWeek
dateLabel.text = calendarInformation.date
}
}

private extension CalendarCollectionViewCell {
func configureUI() {
[dayOfWeekLabel, dateLabel].forEach {
stackView.addArrangedSubview($0)
}
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
}

// MARK: - CalendarInforamtion

struct CalendarInforamtion {
let dayOfWeek: String
let date: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// WorkoutInformationCollectionViewCell.swift
// RecordFeature
//
// Created by 안종표 on 2023/11/16.
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import DesignSystem
import UIKit

// MARK: - WorkoutInformationCollectionViewCell

final class WorkoutInformationCollectionViewCell: UICollectionViewCell {
private let stackView: UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = 6
stackView.alignment = .center
stackView.distribution = .fillEqually
stackView.axis = .vertical
return stackView
}()

private let sportLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body)
label.text = "운동: 사이클"
return label
}()

private let timeLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body)
label.text = "시간: 07:00~08:00"
return label
}()

private let distanceLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body)
label.text = "거리: 12.43km"
return label
}()

override init(frame: CGRect) {
super.init(frame: frame)
}

@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("No Xib")
}

func configure(workoutInformation: WorkoutInformation) {
configureUI()
sportLabel.text = "\(workoutInformation.sport)"
timeLabel.text = "\(workoutInformation.time)"
distanceLabel.text = "\(workoutInformation.distance)"
}
}

private extension WorkoutInformationCollectionViewCell {
func configureUI() {
contentView.backgroundColor = DesignSystemColor.gray01

[sportLabel, timeLabel, distanceLabel].forEach {
stackView.addArrangedSubview($0)
}
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Metrics.leadingTrailingpadding),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Metrics.leadingTrailingpadding),
])
}
}

// MARK: - Metrics

private enum Metrics {
static let leadingTrailingpadding: CGFloat = 10
static let topBottomPadding: CGFloat = 47
}

// MARK: - WorkoutInformation

struct WorkoutInformation {
let sport: String
let time: String
let distance: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// NoRecordsView.swift
// RecordFeature
//
// Created by 안종표 on 2023/11/17.
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import DesignSystem
import UIKit

// MARK: - NoRecordsView

final class NoRecordsView: UIView {
private let noRecordLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "아직 기록이 없습니다\n기록하러 가볼까요?"
label.numberOfLines = 0
label.font = .preferredFont(forTextStyle: .title3)
return label
}()

override init(frame: CGRect) {
super.init(frame: frame)
configureUI()
}

@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("No Xib")
}
}

private extension NoRecordsView {
func configureUI() {
backgroundColor = DesignSystemColor.gray01

addSubview(noRecordLabel)
NSLayoutConstraint.activate([
noRecordLabel.topAnchor.constraint(equalTo: topAnchor, constant: Metrics.topBottomPadding),
noRecordLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: Metrics.leadingTrailing),
noRecordLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -Metrics.leadingTrailing),
noRecordLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Metrics.topBottomPadding),
])
}
}

// MARK: - Metrics

private enum Metrics {
static let topBottomPadding: CGFloat = 35
static let leadingTrailing: CGFloat = 60
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// RecordCalendarViewController.swift
// RecordFeature
//
// Created by 안종표 on 2023/11/18.
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import DesignSystem
import UIKit

// MARK: - RecordCalendarViewController

final class RecordCalendarViewController: UIViewController {
private var dataSource: RecordCalendarDiffableDataSource?
private lazy var calendarCollectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
flowLayout.minimumLineSpacing = 0
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.delegate = self
collectionView.showsHorizontalScrollIndicator = false
return collectionView
}()

override func viewDidLoad() {
super.viewDidLoad()
configureUI()
configureDataSource()
let items = [
CalendarInforamtionItem(dayOfWeek: "화", date: "17"),
CalendarInforamtionItem(dayOfWeek: "화", date: "18"),
CalendarInforamtionItem(dayOfWeek: "화", date: "19"),
CalendarInforamtionItem(dayOfWeek: "화", date: "20"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
CalendarInforamtionItem(dayOfWeek: "화", date: "21"),
]
configureSnapshot(items: items)
}
}

private extension RecordCalendarViewController {
func configureUI() {
view.addSubview(calendarCollectionView)
NSLayoutConstraint.activate([
calendarCollectionView.topAnchor.constraint(equalTo: view.topAnchor),
calendarCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
calendarCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
calendarCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}

func configureDataSource() {
let cellRegistration = RecordCalendarCellRegistration { cell, _, itemIdentifier in
cell.configure(
calendarInformation: CalendarInforamtion(
dayOfWeek: itemIdentifier.dayOfWeek,
date: itemIdentifier.date
)
)
}

dataSource = RecordCalendarDiffableDataSource(
collectionView: calendarCollectionView,
cellProvider: { collectionView, indexPath, itemIdentifier in
collectionView.dequeueConfiguredReusableCell(
using: cellRegistration,
for: indexPath,
item: itemIdentifier
)
}
)
}

func configureSnapshot(items: [CalendarInforamtionItem]) {
var snapShot = RecordCalendarSnapShot()
snapShot.appendSections([.calendar])
snapShot.appendItems(items)
dataSource?.apply(snapShot)
}
}

// MARK: UICollectionViewDelegateFlowLayout

extension RecordCalendarViewController: UICollectionViewDelegateFlowLayout {
func collectionView(
_ collectionView: UICollectionView,
layout _: UICollectionViewLayout,
sizeForItemAt _: IndexPath
) -> CGSize {
return CGSize(width: view.frame.width / 7.5, height: collectionView.frame.height)
}

func collectionView(
_ collectionView: UICollectionView,
didSelectItemAt indexPath: IndexPath
) {
guard let cell = collectionView.cellForItem(at: indexPath) as? CalendarCollectionViewCell else {
return
}
cell.dayOfWeekLabel.textColor = DesignSystemColor.primaryText
cell.dateLabel.textColor = DesignSystemColor.primaryText
}

func collectionView(
_ collectionView: UICollectionView,
didDeselectItemAt indexPath: IndexPath
) {
guard let cell = collectionView.cellForItem(at: indexPath) as? CalendarCollectionViewCell else {
return
}
cell.dayOfWeekLabel.textColor = DesignSystemColor.gray03
cell.dateLabel.textColor = DesignSystemColor.gray03
}
}

private extension RecordCalendarViewController {
typealias RecordCalendarCellRegistration = UICollectionView.CellRegistration<CalendarCollectionViewCell, CalendarInforamtionItem>
typealias RecordCalendarDiffableDataSource = UICollectionViewDiffableDataSource<Section, CalendarInforamtionItem>
typealias RecordCalendarSnapShot = NSDiffableDataSourceSnapshot<Section, CalendarInforamtionItem>
}

// MARK: - Section

private enum Section {
case calendar
}

// MARK: - CalendarInforamtionItem

private struct CalendarInforamtionItem: Identifiable, Hashable {
let id = UUID()
let dayOfWeek: String
let date: String
}
Loading