ios 43일차

bin·2026년 3월 4일

회고

오늘은 기본적인 필수 구현을 마무리하고, 필수 구현 리스트에 존재하지않는 추가 기능들을 구현하고자 했다. 일단, 마이페이지의 레이아웃 구성을 완성하고 내부에 어떤 기능을 담을 지 생각했다. 본인은 이번 과제에서 CoreData를 다루는 것과 CollectionView 및 UI Layout 구성하는 것을 연습하는 것에 중점을 두고자 했다. 때문에, 예매한 영화 내역을 저장하고 불러오며 해당 데이터에 리뷰를 작성할 수 있도록 하는 것과 설정 페이지를 구성하는 것을 해보자 생각했다. 예매 데이터는 팀원이 작업하고 있어서 설정 페이지를 먼저 진행하게 되었다.

과제에 관한 기록

먼저, 설정에서는 어떤 것들을 담고 있어야할까에 대해 생각했다. 당장 시간이 많지않기도 하기 때문에 거창하게 설정 페이지를 만들 수는 없었다. 2가지 정도의 기능을 사용하고 싶었으며 CollectionView의 레이아웃을 CollectionLayoutListConfiguration으로 iPhone의 기본 설정 레이아웃을 사용해보고자 했다. 또한, 지금까지 사용해보지 못한 UICellAccessory도 사용하고자 했다. 구현하기로 한 기능은 비밀번호 변경, 다크모드이다. 비밀번호 변경은 2단계로 나눠서 현재 로그인한 이메일을 UserDefaults에서 받아와서 해당 비밀번호를 확인하고 입력된 현재 비밀번호와 맞는지 검증을 시도한다. 성공하게 될 경우, 비밀번호 변경 로직이 수행되도록 구상했다. 다크모드는 Simulator와 실제 기기의 다크모드 설정을 직접적으로 건드릴 수는 없으나, 해당 앱 내부만이라도 다크모드를 적용하고자 구현했다.

SettingViewController.swift

MypageViewController와 ViewModel에서 NavigateTo 클로저를 통해 해당 셀을 선택할 경우 SettingViewController로 연결되게 구현했다. CollectionViewCell의 Delegate를 채택하여 Switch의 동작 시 메서드를 생성했으며, 다크 모드의 적용 방법은 windowScene의 overrideUserInterfaceStyle을 사용했다.

    func didTapToggleSwitch(isDarkMode: Bool) {
        viewModel.toggleDarkMode(isDarkMode: isDarkMode)
        
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
            windowScene.windows.forEach { window in
                window.overrideUserInterfaceStyle = isDarkMode ? .dark : .light
            }
        }
    }

또한, UICollectionViewDelegate의 didSelectItemAt을 이용하여 비밀번호 변경 정보를 담고있는 셀인지 확인하여 PasswordChangeViewController로 연결해주었다.

SettingViewModel.swift

다크모드 정보를 toggle로 저장하고 불러오는 로직을 담고있으며, 해당 셀이 선택되었을 때 이동할 수 있도록 navigateTo 클로저를 구현하여 ViewController에서 사용할 수 있도록 하였다.

SettingCollectionView.swift

기본적인 Layout 구성은 UICollectionLayoutListConfiguration을 사용했다.

    func createLayout() -> UICollectionViewLayout {
        var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
        config.headerMode = .supplementary
        return UICollectionViewCompositionalLayout.list(using: config)
    }

SettingCollectionViewCell.swift

셀에서 사용될 기본적인 UI 속성 및 Layout을 정의하였으며 ViewController에서 사용하기 위해 Switch의 delegate를 정의했다.

PasswordChangeViewController.swift

ViewModel을 통해 받아온 데이터를 bind하여 적용한다. 또한, 비밀번호 변경 로직이 동작하여 발생하는 성공과 오류 상황에 대해 출력되는 Alert 메서드를 생성하여 사용하고, 비밀번호 성공 시 이후 동작에 대해 정의한다.

PasswordChangeViewModel.swift

TextField에 입력된 값을 담고 있을 변수를 정의하고 사용하며, CoreData를 통해 비밀번호를 검증하고, 업데이트하는 비즈니스 로직을 담고있다. 또한, isInputValid라는 변수를 통해 비밀번호 변경 버튼이 클릭될 수 있는 상태인가를 판단하는 로직도 포함하고 있다.

PasswordChangeView.swift

TableView, CollectionView를 사용하지 않고 UI들을 직접 레이아웃 구성했다. TextField는 지난번에 미리 생성해둔 CustomTextField를 사용했는데, 여기서 문제가 발생한다. CustomTextField라고 생성해둔 class는 사실 TextField가 아닌 TextFiedl를 포함하고 있는 UIView이다. 이로 인해, PasswordChangeView에서 사용하고 있는 TextField들은 동작을 정의하는 addTarget을 사용하지 못한다. 이를 해결하기 위해, CustomTextField 하단에 아래와 같이 textField에 직접적으로 사용할 수 있는 addTarget을 지정해주었다.

extension CustomTextField {
    func addTarget(_ target: Any?, action: Selector, for event: UIControl.Event) {
        self.textField.addTarget(target, action: action, for: event)
    }
}

참조

0개의 댓글