๐ SwiftUI macOS ์ฑ์ ์คํ๋ ์คํฌ๋ฆฐ ์ถ๊ฐ
macOS ์ฑ์ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ์ฑ ์คํ ์ ๋ธ๋๋ ๋ก๊ณ ๋ ๊ฐ๋จํ ์ธํธ๋ก๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ์ค๋์ SwiftUI๋ก ์คํ๋ ์คํฌ๋ฆฐ(์ธํธ๋ก ๋ทฐ)๋ฅผ ๊ตฌ์ฑํ๊ณ , 5์ด ํ ์๋์ผ๋ก ๋ฉ์ธ ํ๋ฉด์ผ๋ก ์ ํ๋๋ ๋ก์ง์ ๊ตฌํํด ๋ณด๊ฒ ์ต๋๋ค.
โจ ์ฃผ์ ๊ธฐ๋ฅ ์๊ฐ
- ์ฑ ์คํ ํ ์คํ๋ ํ๋ฉด์ ๋จผ์ ๋ณด์ฌ์ค๋๋ค.
- ์ฌ์ฉ์๊ฐ ๋ณ๋ ์กฐ์ ์์ด 5์ด ํ ๋ฉ์ธ ํ๋ฉด์ผ๋ก ์ ํ๋ฉ๋๋ค.
- ์คํ๋ ํ๋ฉด์๋ ์ด๋ฏธ์ง, ํ๋ก๊ทธ๋จ ์ด๋ฆ, ๊ฐ๋จํ ์ค๋ช ์ด ํฌํจ๋ฉ๋๋ค.
- ์ฑ ์์๊ณผ ํ ์คํธ๋ ๋ค๊ตญ์ด ๋ก์ปฌ๋ผ์ด์ง์ด ๊ฐ๋ฅํ๋๋ก ๊ตฌ์ฑํ์ต๋๋ค.
๐ก ์ ์ฒด ์ฝ๋ ๊ตฌ์ฑ ์์ฝ
ContentView.swift
struct ContentView: View {
@State private var showOpeningImage = true
var body: some View {
Group {
if showOpeningImage {
OpeningView()
.transition(.opacity)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
withAnimation {
showOpeningImage = false
}
}
}
} else {
MainView() // ์ค์ ์ฑ ๋ฉ์ธ ํ๋ฉด์ผ๋ก ์ ํ
}
}
}
}
@State ๋ณ์์ DispatchQueue๋ฅผ ํ์ฉํ์ฌ ์๊ฐ ๊ธฐ๋ฐ ์ํ ๋ณ๊ฒฝ์ ๊ตฌํํ์์ต๋๋ค.
๐ผ ์คํ๋ ํ๋ฉด UI (OpeningView)
struct OpeningView: View {
var body: some View {
VStack {
HStack {
Image("open_image")
.resizable()
.scaledToFit()
.frame(width: 500, height: 500)
.clipShape(Circle())
.overlay(Circle().stroke(Color.black, lineWidth: 4))
.shadow(radius: 10)
VStack {
Text(NSLocalizedString("OPEN_TEXT", comment: "์ฑ ์ด๋ฆ"))
.font(.title2)
.frame(maxWidth: 300)
.padding()
Text(NSLocalizedString("OPEN_CONTENT", comment: "์ฑ ์ค๋ช
"))
.font(.subheadline)
.multilineTextAlignment(.center)
.frame(maxWidth: 300)
.padding()
Text(NSLocalizedString("OPEN_VERSION", comment: "๋ฒ์ /์ ์๊ถ"))
.font(.footnote)
.multilineTextAlignment(.center)
.frame(maxWidth: 300)
.padding()
}
}
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(hex: NSLocalizedString("COLOR_POP", comment: "๋ฐฐ๊ฒฝ์")))
.edgesIgnoringSafeArea(.all)
}
}
๐ ๋ค๊ตญ์ด ์ง์์ ์ํ ์ค์ (Localizable.strings)
// ํ๊ตญ์ด ๋ฒ์
"OPEN_TEXT" = "๋ ์ง์คํธ๋ฆฌ ๋ถ์๊ธฐ";
"OPEN_CONTENT" = "์์คํ
ํฌ๋ ์ ๋ฐ ๋ณด์ ์ง๋จ ๋๊ตฌ์
๋๋ค.";
"OPEN_VERSION" = "ยฉ 2025. Rho JeongSeok. All rights reserved.";
"COLOR_POP" = "#E6F0FA";
- ๋ฒ์ญ ํ์ผ๋ง ๋ฐ๊พธ๋ฉด ๋ค์ํ ์ธ์ด์ ๋์ ๊ฐ๋ฅํฉ๋๋ค.
- ์ฑ ์ด๋ฆ, ์๊ฐ ๋ฌธ๊ตฌ, ์์๊น์ง ๋ชจ๋ ์ธ๋ถ์์ ์ ์ดํ ์ ์์ด ์ ์ง ๋ณด์๋ ์ฉ์ดํฉ๋๋ค.
๐จ Hex ์์ ์ฌ์ฉํ๊ธฐ
SwiftUI๋ ๊ธฐ๋ณธ์ ์ผ๋ก Hex ์์ ์ฝ๋๋ฅผ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ ํ์ฅ์ ํ์ฉํฉ๋๋ค:
extension Color {
init(hex: String) {
let scanner = Scanner(string: hex)
_ = scanner.scanString("#")
var rgb: UInt64 = 0
scanner.scanHexInt64(&rgb)
let r = Double((rgb >> 16) & 0xFF) / 255
let g = Double((rgb >> 8) & 0xFF) / 255
let b = Double(rgb & 0xFF) / 255
self.init(red: r, green: g, blue: b)
}
}
โ
๊ฐ๋ฐ ํ
- ์คํ๋ ํ๋ฉด์ ์ฑ์ ์ฒซ์ธ์์ ๋๋ค. ๋ธ๋๋ ์ด๋ฏธ์ง๋ ํ์ฌ ๋ก๊ณ ๋ฅผ ๋ด๋ ๋ฐ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ์ธ์.
- onAppear + asyncAfter ์กฐํฉ์ ๊ฐ๋จํ Splash๋ Intro ํ๋ฉด ๊ตฌ์ฑ์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
- ์ฌ์ฉ์์๊ฒ ์๋ด ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ ์ถ์ ๋ Text๋ฅผ ๋์ ์ผ๋ก ๋ฐ๊ฟ๋ณด๋ ๊ฒ๋ ์ข์ต๋๋ค.