본문 바로가기

UIKIT

날짜 선택하기

  • FeedViewController 내의 테이블뷰에 표시될 테이블셀 생성 
  • 테이블 셀을 누르면 sheet형식으로 나올 DatePickerViewController 생성
  • FeedViewController 내의 extension 함수 처리 

 

1. DateAddCell

import UIKit

class DateAddCell: UITableViewCell {
    
    // MARK: - Variables
    static let idenifier: String = "DateAddCell"
    
    // MARK: - UI Components
    let basicView: UIView = {
        let view = UIView()
        view.backgroundColor = .systemBackground
        view.layer.cornerRadius = 10
        view.clipsToBounds = true
        return view
    }()
    
    let titleLabel: UILabel = {
        let label = UILabel()
        label.text = "방문 날짜"
        label.font = .systemFont(ofSize: 16, weight: .bold)
        label.textColor = .label
        return label
    }()
    
    let selectedDateLabel: UILabel = {
        let label = UILabel()
        label.text = "방문하신 날짜를 선택해주세요"
        label.textColor = .label
        label.font = .systemFont(ofSize: 16, weight: .semibold)
        return label
    }()
    
    let rightImageView: UIImageView = {
        let imageView = UIImageView()
        let config = UIImage.SymbolConfiguration(pointSize: 15, weight: .bold)
        let image = UIImage(systemName: "chevron.right", withConfiguration: config)
        imageView.image = image
        imageView.tintColor = .label
        return imageView
    }()
    
    
    // MARK: - Initializations
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        configureConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Layouts
    private func configureConstraints() {
        contentView.addSubview(basicView)
        basicView.addSubview(titleLabel)
        basicView.addSubview(selectedDateLabel)
        basicView.addSubview(rightImageView)
        
        basicView.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        selectedDateLabel.translatesAutoresizingMaskIntoConstraints = false
        rightImageView.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            basicView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            basicView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            basicView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
            basicView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5),
            
            titleLabel.leadingAnchor.constraint(equalTo: basicView.leadingAnchor, constant: 10),
            titleLabel.centerYAnchor.constraint(equalTo: basicView.centerYAnchor),
            
            rightImageView.trailingAnchor.constraint(equalTo: basicView.trailingAnchor, constant: -10),
            rightImageView.centerYAnchor.constraint(equalTo: basicView.centerYAnchor),
            rightImageView.heightAnchor.constraint(equalToConstant: 20),
            rightImageView.widthAnchor.constraint(equalToConstant: 20),
            
            selectedDateLabel.trailingAnchor.constraint(equalTo: rightImageView.leadingAnchor, constant: -10),
            selectedDateLabel.centerYAnchor.constraint(equalTo: basicView.centerYAnchor)
        ])
    }
    
    // MARK: - Functions
    func updateSelectedDate(with selectedDate: String) {
        selectedDateLabel.text = selectedDate
    }
}

 

 

 

2. DatePickerViewController

import UIKit

class DatePickerViewController: UIViewController {

    // MARK: - Variables
    var onDateSelected: ((Date) -> Void)?    // 선택된 날짜를 전달할 클로저
    var initialDate: Date?    // 초기 날짜를 설정할 변수
    
    // MARK: - UI Components
    let titleLabel: UILabel = {
        let label = UILabel()
        label.text = "방문하신 날짜를 선택해주세요"
        label.font = .systemFont(ofSize: 20, weight: .black)
        label.textColor = .label
        label.numberOfLines = 0
        return label
    }()
    
    let datePicker: UIDatePicker = {
        let picker = UIDatePicker()
        picker.datePickerMode = .date   // 하루만 선택 가능하게 설정
        picker.preferredDatePickerStyle = .inline
        picker.date = Date()   // 기본적으로 활성화
        return picker
    }()
    
    let selectedButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("선택 완료", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .black
        button.layer.cornerRadius = 10
        button.clipsToBounds = true
        button.isEnabled = false
        return button
    }()
    
    
    // MARK: - Initializations
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemBackground
        view.addSubview(datePicker)
        view.addSubview(selectedButton)
        
        configureContraints()
        
        datePicker.addTarget(self, action: #selector(changedDate), for: .valueChanged)
        selectedButton.addTarget(self, action: #selector(selectButtonTapped), for: .touchUpInside)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        if let initialDate = initialDate {
            datePicker.date = initialDate
            selectedButton.isEnabled = true
        }
    }
    
    // MARK: - Layouts
    private func configureContraints() {
        view.addSubview(titleLabel)
        view.addSubview(datePicker)
        view.addSubview(selectedButton)
        
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        datePicker.translatesAutoresizingMaskIntoConstraints = false
        selectedButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            
            datePicker.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            datePicker.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -20),
            
            selectedButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            selectedButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
            selectedButton.topAnchor.constraint(equalTo: datePicker.bottomAnchor, constant: 10),
            selectedButton.heightAnchor.constraint(equalToConstant: 50),
            
        ])
    }
    
    
    // MARK: - Actions
    @objc private func selectButtonTapped() {
        onDateSelected?(datePicker.date) // 선택한 날짜 전달
        dismiss(animated: true, completion: nil)
    }
    
    @objc private func changedDate() {
        selectedButton.isEnabled = true
    }
}

 

 

3. FeedViewController

import UIKit
import PhotosUI

class FeedViewController: UIViewController {
    
    // MARK: - Variables
    var selectedDate: Date?
    ...
    
        func setupTableView() {
        feedTableView.delegate = self
        feedTableView.dataSource = self
        feedTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        feedTableView.register(PhotoAddCell.self, forCellReuseIdentifier: PhotoAddCell.identifier)
        feedTableView.register(TextInputCell.self, forCellReuseIdentifier: TextInputCell.identifier)
        feedTableView.register(SpaceAddCell.self, forCellReuseIdentifier: SpaceAddCell.identifier)
        feedTableView.register(DateAddCell.self, forCellReuseIdentifier: DateAddCell.idenifier)
    }
    
    ...
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch (indexPath.section, indexPath.row) {
		...
        case (2, 1):
            guard let cell = tableView.dequeueReusableCell(withIdentifier: DateAddCell.idenifier, for: indexPath) as? DateAddCell else { return UITableViewCell() }
            
            cell.selectionStyle = .none
            return cell
        ...
        
        
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        ...
        if indexPath.section == 2 && indexPath.row == 1 {
            let datePickerVC = DatePickerViewController()
            datePickerVC.modalPresentationStyle = .pageSheet
            
            // 초기 날짜를 설정하여 DatePicker 초기화
            if let currentSelectedDate = selectedDate { // 이미 선택된 날짜가 있으면 사용
                datePickerVC.initialDate = currentSelectedDate
            } else { // 선택된 날짜가 없다면 기본값을 오늘로 설정
                datePickerVC.initialDate = Date()
            }
            
            if let sheet = datePickerVC.sheetPresentationController {
                sheet.detents = [.medium(), .large()]
                sheet.prefersGrabberVisible = true
            }
            
            // 날짜 선택 시 동작
            datePickerVC.onDateSelected = { [weak self] selectedDate in
                guard let self = self else { return }
                self.selectedDate = selectedDate // 새로운 날짜 저장
                
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyy-MM-dd"
                let dateString = dateFormatter.string(from: selectedDate)
                
                guard let cell = tableView.cellForRow(at: indexPath) as? DateAddCell else { return }
                cell.selectedDateLabel.text = dateString
            }
            present(datePickerVC, animated: true)
        }
        
    }
}