TIL

41일차 TIL

h_luz 2024. 4. 24. 21:26

 

팀프로젝트 : MegaStruct
스파르타코딩클럽

 

PickerView로 시간 선택하는 기능 구현하기

 

 

1 시간과 날짜를 버튼 눌러서 pickerView로 변환할 수 있도록 스토리보드에 생성해 줬다 

우선 시간부터 pickerView로 구현해보려고 한다.

 

pickerView( _:titleForRow: forComponent: )

https://developer.apple.com/documentation/uikit/uipickerviewdelegate/1614384-pickerview

 

pickerView(_:titleForRow:forComponent:) | Apple Developer Documentation

Called by the picker view when it needs the title to use for a given row in a given component.

developer.apple.com

 

이런 게 pickerView임 

버튼 클릭 시 alert창을 밑에 띄워서 선택하는 방식으로 구현하고자 한다.

 

시간 선택 코드 구현

스토리보드에 버튼과 연결 (처음은 현재 시간으로)

alert창으로 pickerView 띄우도록 코드 구현

버튼 클릭 시 pickerView 띄우도록 IBAction으로 연결해 주고, showTimePicker() 실행

 

updateTimeButton() 함수

 

앱 실행 시 뜨는 시간은 현재 시간으로 표시하기 위해 updateTimeButton(date: selectedTime)을 viewDidLoad()에 넣어주기

 

엥 근데 이렇게 뜸 ㅋ ㅠ

 

https://rldd.tistory.com/94

이 블로그를 참고했는데,

showTimePicker() 에 alert창의 높이를 조절하는 코드를 추가해 주면 

 

잘 나오는 것을 확인할 수 있음 ㅜㅜ 

 

하 저것 때문에 customPopup까지 해봤다가 돌아왔다..

 

그래서 chatGPT에게 alert창과 customPopup의 장단점을 물어봤음!

시간을 정하는 간단한 문제라서 Alert가 나은 것 같음 ㅎㅎ 굿

 

customPopup 너무 복잡하더라...ㅠ

그렇지만 나중에 다른 기능을 구현할 때 사용할 수 있으니 알아두는 건 좋은 것 같음!

 

customPopup으로 구현했던 거..

더보기

 

import UIKit

 

class TicketingController: UIViewController {

 

    @IBOutlet weak var timeSelectButton: UIButton!

    var selectedTime: Date = Date() // 처음은 현재 시간으로 설정

 

    override func viewDidLoad() {

        super.viewDidLoad()

        // 앱 실행 시 현재 시간 버튼에 표시

        updateTimeButton(date: selectedTime)

    }

 

    // 날짜/시간 선택 버튼 클릭 시

    @IBAction func timeTapped(_ sender: Any) {

        showCustomTimePicker()

    }

 

    // 커스텀 팝업으로 시간 선택

    func showCustomTimePicker() {

        let popupVC = UIViewController()

        popupVC.view.backgroundColor = UIColor.white

        

        let pickerView = UIDatePicker()

        pickerView.datePickerMode = .time

        pickerView.preferredDatePickerStyle = .wheels

        pickerView.translatesAutoresizingMaskIntoConstraints = false

        popupVC.view.addSubview(pickerView)

        

        // UIDatePicker 레이아웃 설정

        pickerView.centerXAnchor.constraint(equalTo: popupVC.view.centerXAnchor).isActive = true

        pickerView.centerYAnchor.constraint(equalTo: popupVC.view.centerYAnchor).isActive = true

 

        // 팝업 창 크기 및 위치 설정

        popupVC.modalPresentationStyle = .custom

        popupVC.transitioningDelegate = self // 설정한 custom presentation을 위한 transitioning delegate 지정

 

        // 팝업 창 띄우기

        present(popupVC, animated: true, completion: nil)

        

        // 선택 버튼

        let selectButton = UIButton(type: .system)

        selectButton.setTitle("선택", for: .normal)

        selectButton.addTarget(self, action: #selector(handleTimeSelection(_:)), for: .touchUpInside)

        popupVC.view.addSubview(selectButton)

        

        // 버튼 레이아웃 설정

        selectButton.translatesAutoresizingMaskIntoConstraints = false

        selectButton.topAnchor.constraint(equalTo: pickerView.bottomAnchor, constant: 20).isActive = true

        selectButton.centerXAnchor.constraint(equalTo: popupVC.view.centerXAnchor).isActive = true

    }

 

    // 시간 선택 완료 시

    @objc func handleTimeSelection(_ sender: UIButton) {

        if let presentedVC = presentedViewController {

            if let pickerView = presentedVC.view.subviews.first as? UIDatePicker {

                selectedTime = pickerView.date

                updateTimeButton(date: selectedTime)

            }

            presentedVC.dismiss(animated: true, completion: nil)

        }

    }

 

    // 버튼에 선택된 시간 표시

    func updateTimeButton(date: Date) {

        let dateFormatter = DateFormatter()

        dateFormatter.dateFormat = "hh:mm a" // 예: "04:24 PM"

        let timeString = dateFormatter.string(from: date)

        timeSelectButton.setTitle(timeString, for: .normal)

    }

}

 

// Custom Presentation을 위한 UIViewControllerTransitioningDelegate 구현

extension TicketingController: UIViewControllerTransitioningDelegate {

    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {

        return CustomPresentationController(presentedViewController: presented, presenting: presenting)

    }

}

 

// Custom UIPresentationController 클래스 구현

class CustomPresentationController: UIPresentationController {

    override var frameOfPresentedViewInContainerView: CGRect {

        guard let containerView = containerView else { return CGRect.zero }

        

        let screenWidth = containerView.bounds.width // 화면 너비

        let popupWidth: CGFloat = screenWidth - 40 // 팝업 너비는 화면 너비에서 여백(예: 20)을 뺀 값

        let height: CGFloat = 200

        let x = (containerView.bounds.width - popupWidth) / 2

        let y = containerView.bounds.height - height - 50 // 원하는 높이에 따라 조절

        

        return CGRect(x: x, y: y, width: popupWidth, height: height)

    }

}

 


 

날짜 선택하는 기능 구현하기

https://kasroid.github.io/posts/ios/20201030-uikit-date-picker/

 

UIKit - Date Picker 사용하기, iOS 14 변경사항 정리

본 포스팅은 다음 버전을 기준으로 작성되었습니다. Swift 5.3 iOS 14.1 Intro 이전 포스트에서 Date 에 관해 알아보았으니 이번에는 사용자가 아이폰에서 날짜를 고를 때 자주 마주치게되는 인터페이

kasroid.github.io

 

일단 원래는 위에 한 것처럼 wheel 형식인데 iOS14 이후로 캘린더? 모양으로 변경되었다고 하는데

일단은 시간과 같은 방식으로 구현하고, 시간이 남으면 캘린더 모양도 도전해 보자 :)

그냥 시간 구현한 거랑 거의 똑같음..

 

 


 

이제 + 버튼을 누르면 인원수가 증가하고 -버튼을 누르면 인원수가 감소하는  버튼을 만들건대

전에 프로젝트에서는 +랑 -를 따로 버튼 한 개씩 만들어서 연결했었음..

근데 찾아보니 stepper이라는 값을 늘리거나 줄일 수 있는 기능이 있었다..! ㅜㅠ

 

https://developer.apple.com/documentation/uikit/uistepper

 

UIStepper | Apple Developer Documentation

A control for incrementing or decrementing a value.

developer.apple.com

 

stepper은 이렇게 생겼음!

 

코드나 디자인적으로도 훨씬 깔끔함 ㅜㅜ

minimun은 1이고, maximum은 8로 설정했다 ( 실제 메가박스 예매가 최대 8인까지 예매 가능하게 되어있음! )

vieDidLoad에 함수 호출하는 것도 잊지 말기..

 


 

그리고 인원수에 따른 총 가격 변동 기능을 구현할 것이다.

인원수가 증가하면 당연히 결제 값도 증가하는데 기본 1인당 영화 가격은 15000원이다.

인원수에 따라 총가격을 계산하고, 총 가격 레이블을 업데이트해 준다 

총 가격 계산할 때 stepper의 value값을 사용하기 때문에 stepperValueChanged 함수가 액션 할 때 업데이트된 value 값을 사용하도록 calculateTotalPrice()를 이 함수에 입력해주어야 한다.

viewDidLoad에 총 가격 레이블 업데이트까지 해주면 완료

 

 


 

천 단위로 쉼표 찍어주기를 하려면, updateTotalPriceLabel()을 수정해 주면 됨

 

완성

 


 

스탠더드반 강의 정리

https://fluffy-brie-4fd.notion.site/5-d213e0044313413cabf439c70a202de2

 

DispatchQueue에 대해서 더 자세히 알아서 좋았음 

전에 정리해서 그런가 더 잘 들리는 것 같았음

정리하려고 했는데 넘.. 힘들다 ㅇ..

 

ㅎㅎ

'TIL' 카테고리의 다른 글

43일차 TIL  (1) 2024.04.26
42일차 TIL  (0) 2024.04.25
40일차 TIL  (0) 2024.04.23
38일차 TIL  (1) 2024.04.19
37일차 TIL  (3) 2024.04.18