Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions PickaView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
objectVersion = 77;
objects = {

/* Begin PBXBuildFile section */
8D0EA2B42DF81B1E005AA031 /* DGCharts in Frameworks */ = {isa = PBXBuildFile; productRef = 8D0EA2B32DF81B1E005AA031 /* DGCharts */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
8D20CDCA2DF1728900D1D063 /* PickaView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PickaView.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -36,6 +40,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D0EA2B42DF81B1E005AA031 /* DGCharts in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -78,6 +83,7 @@
);
name = PickaView;
packageProductDependencies = (
8D0EA2B32DF81B1E005AA031 /* DGCharts */,
);
productName = PickaView;
productReference = 8D20CDCA2DF1728900D1D063 /* PickaView.app */;
Expand Down Expand Up @@ -107,6 +113,9 @@
);
mainGroup = 8D20CDC12DF1728900D1D063;
minimizedProjectReferenceProxies = 1;
packageReferences = (
8D0EA2B22DF81B1E005AA031 /* XCRemoteSwiftPackageReference "Charts" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 8D20CDCB2DF1728900D1D063 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -341,6 +350,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
8D0EA2B22DF81B1E005AA031 /* XCRemoteSwiftPackageReference "Charts" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ChartsOrg/Charts";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 5.1.0;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
8D0EA2B32DF81B1E005AA031 /* DGCharts */ = {
isa = XCSwiftPackageProductDependency;
package = 8D0EA2B22DF81B1E005AA031 /* XCRemoteSwiftPackageReference "Charts" */;
productName = DGCharts;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 8D20CDC22DF1728900D1D063 /* Project object */;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions PickaView/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@
</objects>
<point key="canvasLocation" x="1978" y="120"/>
</scene>
<!--Tab Bar Controller-->
<!--Main View Controller-->
<scene sceneID="kSv-3O-sWd">
<objects>
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="T1G-iv-UrV" sceneMemberID="viewController">
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="T1G-iv-UrV" customClass="MainViewController" customModule="PickaView" customModuleProvider="target" sceneMemberID="viewController">
<toolbarItems/>
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="nKz-Te-FSR">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
Expand Down
75 changes: 75 additions & 0 deletions PickaView/Data/UserDefault/ThemeManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// UserDefault.swift
// PickaView
//
// Created by Ko Minhyuk on 6/10/25.
//

import UIKit

/// 앱의 인터페이스 스타일(테마)을 관리하는 싱글턴 클래스.
final class ThemeManager {

/// ThemeManager의 유일한 인스턴스에 접근하기 위한 정적 프로퍼티.
static let shared = ThemeManager()

/// UserDefaults에 테마 설정을 저장하기 위한 키.
private let themeKey = "appTheme"

/// 가독성을 위해 정수 인덱스 대신 열거형(enum)을 사용.
enum ThemeOption: Int {
case light = 0
case dark = 1
case system = 2
}

// 외부에서 인스턴스를 직접 생성하지 못하도록 private으로 설정.
private init() {}

/// UserDefaults에 저장된 테마 인덱스를 불러오는 계산 프로퍼티.
var currentThemeIndex: Int {
return UserDefaults.standard.integer(forKey: themeKey)
}

/**
저장된 테마 설정을 앱의 모든 윈도우에 즉시 적용함.

앱이 시작될 때 `MainViewController`에서 호출됨.
*/
func applyTheme() {
let themeIndex = UserDefaults.standard.integer(forKey: themeKey)
guard let theme = ThemeOption(rawValue: themeIndex) else { return }

let style: UIUserInterfaceStyle
switch theme {
case .light: style = .light
case .dark: style = .dark
case .system: style = .unspecified
}

// Scene-based API를 사용하여 현재 활성화된 모든 윈도우에 테마를 적용.
UIApplication
.shared
.connectedScenes
.compactMap { $0 as? UIWindowScene }
.forEach { windowScene in
windowScene.windows.forEach { window in
window.overrideUserInterfaceStyle = style
}
}
}

/*
새로운 테마 설정을 저장하고 즉시 적용함.

`MyPageViewController`의 세그먼트 컨트롤에서 호출됨.
- Parameter selectedIndex: 사용자가 선택한 새로운 테마의 인덱스.
*/
func setTheme(selectedIndex: Int) {
// 1. UserDefaults에 새로운 선택을 저장.
UserDefaults.standard.set(selectedIndex, forKey: themeKey)

// 2. 변경된 테마를 앱에 바로 적용.
applyTheme()
}
}
18 changes: 18 additions & 0 deletions PickaView/MainViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// MainViewController.swift
// PickaView
//
// Created by Ko Minhyuk on 6/10/25.
//

import UIKit

class MainViewController: UITabBarController {

override func viewDidLoad() {
super.viewDidLoad()

ThemeManager.shared.applyTheme()
print("initial")
}
}
37 changes: 28 additions & 9 deletions PickaView/Views/MyPage/MyPage.storyboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="C4A-Sc-eyi">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
Expand All @@ -9,22 +9,41 @@
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--MyPage-->
<scene sceneID="s0d-6b-0kx">
<!--Setting-->
<scene sceneID="g9e-EM-NR9">
<objects>
<viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<viewController id="oSK-Jy-vbr" customClass="MyPageViewController" customModule="PickaView" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="dAa-rk-RtC">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<viewLayoutGuide key="safeArea" id="ByT-wo-zUn"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<tabBarItem key="tabBarItem" title="MyPage" image="ellipsis" catalog="system" id="jsI-ZY-P3R"/>
<navigationItem key="navigationItem" title="Setting" id="cbF-DS-Ep1"/>
<simulatedTabBarMetrics key="simulatedBottomBarMetrics"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="2ab-kp-XHZ" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1324.4274809160304" y="-209.1549295774648"/>
</scene>
<!--MyPage-->
<scene sceneID="eXe-1e-hZc">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="C4A-Sc-eyi" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="MyPage" image="ellipsis" catalog="system" id="6zh-5E-tIH"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="G0W-L3-TLD">
<rect key="frame" x="0.0" y="118" width="393" height="96"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="oSK-Jy-vbr" kind="relationship" relationship="rootViewController" id="HIi-yn-NL5"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yrK-Qo-ece" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="-34"/>
<point key="canvasLocation" x="397.70992366412213" y="-209.1549295774648"/>
</scene>
</scenes>
<resources>
Expand Down
Loading