iOS 프로그래밍 실무 3주차
ChatGPT로 iOS 무드등 앱 만들기
무드등 iOS 앱 사전 계획서
1. 프로젝트 개요
- 앱 이름: (추후 결정)
- 앱 유형: 무드등 및 조명 컨트롤 앱
- 대상 사용자: 감성적인 조명을 활용하고 싶은 일반 사용자, 수면 조명이 필요한 사용자
2. 주요 기능
- 기본 무드등 기능
- 다양한 컬러 설정 (RGB 색상 선택)
- 밝기 조절 기능
- 타이머 기능 (지정된 시간 후 자동 종료)
- 프리셋 & 테마
- 감성적인 조명 테마 제공 (예: 로맨틱, 집중, 숙면 등)
- 사용자가 직접 커스텀 테마 생성 및 저장 가능
- 음악 & 조명 연동
- 음악을 재생하면 리듬에 맞춰 색상이 변하는 기능
- 앱 내 사운드스케이프 (빗소리, 자연의 소리 등) 제공
- 위젯 & 단축어 지원
- 홈 화면 위젯에서 간단한 조작 가능
- Siri 단축어 연동으로 음성 명령 실행
- 수면 모드
- 서서히 밝아지는 기상 조명
- 취침 전 점점 어두워지는 기능
- IoT 기기 연동 (추후 지원 가능)
- 스마트 조명 (Philips Hue 등)과 연동
3. UI/UX 디자인
- 심플하고 직관적인 UI (버튼 최소화, 제스처 기반 컨트롤 지원)
- 다크 모드 지원
- 부드러운 애니메이션 효과 적용
- 사용자 맞춤 테마 기능 추가
4. 기술 스택
- 프레임워크: SwiftUI
- 데이터 저장: UserDefaults, CoreData
- 오디오 기능: AVFoundation
- 위젯 지원: WidgetKit
- 단축어 연동: SiriKit
5. 마케팅 & 수익 모델
- 기본 무료 제공, 프리미엄 기능 유료화 (In-App Purchase)
- 광고 없는 유료 버전 제공 (일회성 구매 또는 구독 모델 고려)
- SNS 공유 기능으로 바이럴 유도
6. 개발 일정 (예상)
- 1주차: 시장 조사 및 기획 정리
- 2~3주차: UI/UX 디자인 및 프로토타입 제작
- 4~6주차: 핵심 기능 개발
- 7~8주차: 테스트 및 피드백 반영
- 9주차: 앱스토어 심사 및 출시
무드등 iOS 앱 개발 일정표
1. 3월 (기획 및 설계)
- 3월 19일 ~ 3월 24일: 시장 조사 및 인기 앱 분석
- 3월 25일 ~ 3월 31일: 기능 정의 및 개발 계획 확정
- 3월 31일: 와이어프레임 및 UI 디자인 초안 완성
2. 4월 (기능 개발 & UI 작업)
- 4월 1일 ~ 4월 7일:
- 기본 무드등 기능 개발 (색상 변경, 밝기 조절)
- SwiftUI 기반 UI 구축 시작
- 4월 8일 ~ 4월 14일:
- 프리셋 & 테마 기능 개발
- 사용자 설정 저장 기능 (UserDefaults 활용)
- 4월 15일 ~ 4월 21일:
- 음악 연동 기능 (AVFoundation 활용)
- 타이머 기능 구현
- 4월 22일 ~ 4월 30일:
- UI/UX 개선 및 애니메이션 적용
- 위젯 및 Siri 단축어 지원 개발
3. 5월 (테스트 & 마무리 작업)
- 5월 1일 ~ 5월 7일:
- 기본 기능 완성 후 내부 테스트
- 버그 수정 및 UI 개선
- 5월 8일 ~ 5월 14일:
- 앱스토어 제출을 위한 최적화 작업
- 성능 개선 및 추가 테스트
- 5월 15일: 앱스토어 심사 제출
- 5월 16일 ~ 5월 30일:
- 앱스토어 피드백 반영 및 수정
- 마케팅 자료 준비
- 5월 31일: 정식 출시 🎉
무드등 iOS 앱 개발 업무 분담표
1. 역할 분배
역할 | 담당자 | 주요 업무 |
PM & UI/UX 디자이너 | A | - 프로젝트 기획 및 일정 관리 - UI/UX 디자인 및 프로토타입 제작 - 앱스토어 출시 및 마케팅 |
iOS 개발자 (프론트엔드) | B | - SwiftUI 기반 UI 구현 - 애니메이션 및 인터랙션 개발 - 위젯 및 Siri 단축어 기능 개발 |
iOS 개발자 (백엔드 & 데이터 관리) | C | - 주요 기능 개발 (색상 변경, 밝기 조절, 타이머 등) - 음악 연동 (AVFoundation 활용) - 데이터 저장 (UserDefaults, CoreData) |
2. 상세 일정 및 역할별 업무
📌 3월 (기획 및 설계)
A (PM & UI/UX 디자이너)
- 시장 조사 및 기능 정의
- 와이어프레임 및 UI 디자인 제작
B (iOS 프론트엔드 개발자)
- SwiftUI 학습 및 초기 구조 설계
C (iOS 백엔드 개발자)
- 데이터 모델 설계 (UserDefaults, CoreData)
📌 4월 (기능 개발 & UI 작업)
A (PM & UI/UX 디자이너)
- UI 디자인 확정 후 프론트 개발자와 협업
- 애니메이션 및 UX 개선안 제안
B (iOS 프론트엔드 개발자)
- 무드등 UI 구축 (색상 변경, 밝기 조절)
- 프리셋 테마 적용 및 인터랙션 개발
- 위젯 및 Siri 단축어 지원 개발
C (iOS 백엔드 개발자)
- 음악 연동 기능 개발
- 타이머 기능 구현
- 데이터 저장 로직 적용
📌 5월 (테스트 & 배포 준비)
A (PM & UI/UX 디자이너)
- 전체 앱 디자인 및 UI 최적화
- 앱스토어 마케팅 자료 준비
B (iOS 프론트엔드 개발자)
- UI 및 애니메이션 최적화
- 앱스토어 심사 준비
C (iOS 백엔드 개발자)
- 최종 버그 수정 및 성능 개선
- 앱스토어 제출 및 심사 대응
XCode 리와인드
앱을 실행할 수 있는 버전
하나의 앱을 만들면 아이패드, 아이맥, 아이폰 등에서 가능
앱스토어의 식별자, 유일해야 앱스토어에 들어간다
import UIKit // UIKit 프레임워크를 가져옴 (iOS UI 관련 기능 제공)
class ViewController: UIViewController {
// ViewController 클래스 선언 (UIViewController를 상속받음)
override func viewDidLoad() {
super.viewDidLoad() // 부모 클래스의 viewDidLoad() 호출 (기본적인 뷰 로드 작업 수행)
print("viewDidLoad") // viewDidLoad가 실행되었을 때 콘솔에 메시지 출력
}
override func viewWillAppear(_ animated: Bool) {
// 뷰가 화면에 나타나기 직전에 호출됨
// animated 값이 true이면 애니메이션과 함께 나타남
print("viewWillAppear") // viewWillAppear가 실행되었을 때 콘솔에 메시지 출력
}
override func viewDidAppear(_ animated: Bool) {
// 뷰가 화면에 나타난 직후에 호출됨
print("viewDidAppear") // viewDidAppear가 실행되었을 때 콘솔에 메시지 출력
}
}
View Life Cycle
https://developer.apple.com/documentation/uikit/uiviewcontroller
UIViewController | Apple Developer Documentation
An object that manages a view hierarchy for your UIKit app.
developer.apple.com
- ViewDidLoad: 앱이 실행됐을 때 딱 한번만 실행된다.
- 앱에는 여러가지 View가 있는데, 5가지 단계의 상태가 있다.
//
// AppDelegate.swift
// NightLight
//
// Created by redmist on 3/19/25.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 애플리케이션이 시작될 때 사용자 정의 설정을 적용할 수 있는 지점입니다.
return true
}
// MARK: UISceneSession 라이프사이클
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// 새로운 Scene 세션이 생성될 때 호출됩니다.
// 이 메서드를 사용하여 새 Scene을 생성할 구성 정보를 선택할 수 있습니다.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// 사용자가 Scene 세션을 삭제했을 때 호출됩니다.
// 애플리케이션이 실행되지 않은 동안 삭제된 세션이 있다면, application:didFinishLaunchingWithOptions 이후에 호출됩니다.
// 삭제된 Scene과 관련된 리소스를 해제하는 데 사용할 수 있습니다.
}
}
📌 AppDelegate.swift 간단 설명
AppDelegate는 앱의 생명주기(Lifecycle)를 관리하는 핵심 클래스입니다. 앱이 실행되거나 종료될 때 필요한 작업을 처리합니다.
📌 주요 역할
- 앱이 실행될 때 (didFinishLaunchingWithOptions)
- 초기 설정을 수행하는 메서드 (예: Firebase 설정, UserDefaults 로드 등)
- return true를 반환하면 앱이 정상 실행됨
- 새로운 화면(Scene)이 생성될 때 (configurationForConnecting)
- iOS 13부터 추가된 멀티 윈도우(Scene) 지원을 위한 설정
- 기본적으로 "Default Configuration"을 반환하여 앱이 정상 작동하도록 함
- 사용자가 Scene을 닫았을 때 (didDiscardSceneSessions)
- 불필요한 리소스를 해제할 수 있는 메서드
📌 실행 흐름
- 앱 실행 → didFinishLaunchingWithOptions 실행
- 새로운 Scene 생성 → configurationForConnecting 실행
- 사용자가 Scene 종료 → didDiscardSceneSessions 실행
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("앱 실행됨") // 앱 실행 시 콘솔 출력
return true
}
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
print("사용자가 Scene을 종료함") // Scene 종료 시 콘솔 출력
}
}
//
// SceneDelegate.swift
// NightLight
//
// Created by redmist on 3/19/25.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
📌 SceneDelegate.swift 파일 설명
iOS 13부터 멀티 윈도우(Scene) 지원이 도입되면서, 앱의 화면(Scene) 생명주기를 관리하는 SceneDelegate가 추가되었습니다.
이 파일은 앱의 화면이 생성, 활성화, 비활성화, 백그라운드 전환될 때 수행할 작업을 정의합니다.
📌 주요 역할
메서드 | 실행 시점 | 역할 |
scene(_:willConnectTo:options:) | Scene이 처음 생성될 때 | 초기 설정 및 화면 연결 |
sceneDidDisconnect(_:) | Scene이 종료될 때 | 리소스 해제 |
sceneDidBecomeActive(_:) | 앱이 활성화될 때 | 중단된 작업 재개 |
sceneWillResignActive(_:) | 앱이 비활성화될 때 | 일시 중지할 작업 처리 (예: 전화 수신) |
sceneWillEnterForeground(_:) | 백그라운드 → 포그라운드 전환 시 | UI 업데이트, 데이터 복원 |
sceneDidEnterBackground(_:) | 포그라운드 → 백그라운드 전환 시 | 데이터 저장, 리소스 정리 |
📌 코드 상세 설명
1. window 변수
var window: UIWindow?
- 앱의 주 화면(UI) 을 표시하는 창(Window)
- Storyboard를 사용할 경우 자동으로 설정됨
2. Scene이 처음 생성될 때 (willConnectTo)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
- Scene이 처음 연결될 때 실행됨
- 앱의 UI를 구성하고 window를 설정하는 역할
- Storyboard를 사용하면 자동으로 설정되므로 추가 작업이 필요 없음
📌 예제 (코드로 직접 초기화할 경우)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = ViewController() // 기본 ViewController 설정
self.window = window
window.makeKeyAndVisible()
}
3. Scene이 종료될 때 (sceneDidDisconnect)
func sceneDidDisconnect(_ scene: UIScene) {
// Scene이 종료될 때 호출됨 (예: 사용자가 앱을 닫았을 때)
}
- 앱이 실행 중이지만 특정 Scene이 삭제되었을 때 실행됨
- 보통 리소스를 해제하거나, 저장할 데이터가 있으면 저장하는 역할
4. Scene이 활성화될 때 (sceneDidBecomeActive)
func sceneDidBecomeActive(_ scene: UIScene) {
// Scene이 활성화될 때 (예: 홈 버튼에서 다시 앱으로 돌아올 때)
}
- 앱이 사용 가능한 상태가 되면 실행됨
- 일시 정지된 작업을 재개하는 데 사용됨 (예: 음악 재생, 타이머 재개)
5. Scene이 비활성화될 때 (sceneWillResignActive)
func sceneWillResignActive(_ scene: UIScene) {
// Scene이 비활성화될 때 (예: 전화가 올 때)
}
- 앱이 일시 중지 상태로 전환될 때 실행됨
- 중요한 데이터를 저장하거나, 애니메이션을 중단하는 데 사용됨
📌 예제 (일시 정지할 때 실행할 코드)
func sceneWillResignActive(_ scene: UIScene) {
print("앱이 비활성화됨, 현재 상태 저장 필요")
}
6. Scene이 포그라운드로 돌아올 때 (sceneWillEnterForeground)
func sceneWillEnterForeground(_ scene: UIScene) {
// 앱이 백그라운드에서 포그라운드로 전환될 때 호출됨
}
- 앱이 백그라운드에서 다시 활성화될 때 실행됨
- 화면을 갱신하거나, 네트워크 연결을 복원하는 역할
📌 예제 (백그라운드에서 돌아올 때 UI 업데이트)
func sceneWillEnterForeground(_ scene: UIScene) {
print("앱이 포그라운드로 복귀")
}
7. Scene이 백그라운드로 이동할 때 (sceneDidEnterBackground)
func sceneDidEnterBackground(_ scene: UIScene) {
// 앱이 백그라운드로 전환될 때 실행됨
}
- 앱이 백그라운드로 전환될 때 실행됨
- 데이터를 저장하거나, 실행 중인 작업을 정리하는 역할
📌 예제 (UserDefaults에 데이터 저장)
func sceneDidEnterBackground(_ scene: UIScene) {
UserDefaults.standard.set("저장할 값", forKey: "key")
}
📌 정리
- SceneDelegate.swift는 앱의 화면(Scene) 생명주기 관리
- 앱 실행, 비활성화, 백그라운드 전환 시 처리할 작업을 정의
- 앱이 백그라운드로 가면 데이터 저장, 포그라운드로 돌아오면 UI 업데이트
App Life Cycle
Foreground Mode
- Active : 앱이 전경에 있고 이벤트를 받고 있음. 일반적으로 사용자와 상호작용하는 동안 앱은 이 상태에 있음
- nactive : 앱이 전경에 있지만 이벤트를 받고 있지 않음
Background Mode
- Running : 앱이 백그라운드에 있지만 여전히 코드를 실행. 사용자가 다른 앱으로 전환하거나 홈 화면으로 돌아갔을 때 앱은 일시적으로 이 상태에 머물게 됨
- Suspend : 앱이 백그라운드에 있지만 코드를 실행하지 않음. 시스템은 앱을 이 상태로 자동으로 전환하며 필요에 따라 메모리를 회수하기 위해 앱을 종료시킬 수 있음.
뷰(View)
view
- UI를 구성하는 요소, 모든 뷰는 UIKIit의 UIView 클래스의 자식클래스
부모 또는 수퍼뷰(superview)/자식 또는 서브뷰(subview)
부모
- super view
자식
- subview, 언제나 부모 뷰의 틀 안에서 보여진다
컨테이너 뷰(container view)
여러 개의 뷰 컨트롤러를 포함하고, 그 사이를 전환하는 역할
UINavigationController
- 뷰 컨트롤러 간의 계층적 네비게이션을 관리
- 리스트에서 항목을 선택하면 상세 화면으로 이동하거나, 여러 단계를 거쳐 정보를 입력하는 등의 작업에 사용
UITabBarController
- 뷰 컨트롤러 간의 평행 네비게이션을 관리
- 앱의 주요 기능을 각각의 탭으로 나누고 사용자가 원하는 탭을 선택하여 해당 기능을 이용할 수 있게 하는 데 사용
* UISplitViewController: 아이패드 용
앱을 실행하면 배경색을 파란색으로 변경
view는 UIViewController 클래스의 기본 속성으로, 현재 뷰 컨트롤러에서 관리하는 뷰를 가리킵니다. 즉, 화면에 표시되는 UI 요소들을 담고 있는 컨테이너입니다.
UIViewController는 앱에서 화면 하나를 담당하는 컨트롤러로, 해당 화면에 표시되는 뷰를 view 속성을 통해 접근하고 관리할 수 있습니다.
예시 설명:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.blue // view는 현재 뷰 컨트롤러의 뷰를 참조
}
}
- view.backgroundColor = UIColor.blue:
- view는 ViewController의 화면에 해당하는 뷰를 의미합니다.
- view.backgroundColor를 설정하여 해당 화면의 배경 색을 파란색으로 설정합니다.
따라서, view는 화면을 구성하는 뷰로, 이 안에 UI 요소들이 배치되고, 화면에 표시되는 모든 콘텐츠를 담는 공간입니다.
1초마다 배경색 랜덤으로 변경되는 소스
import UIKit
class ViewController: UIViewController {
var colorChangeTimer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
colorChangeTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
let red = CGFloat(arc4random_uniform(256)) / 255.0
let green = CGFloat(arc4random_uniform(256)) / 255.0
let blue = CGFloat(arc4random_uniform(256)) / 255.0
self.view.backgroundColor = UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
colorChangeTimer?.invalidate()
colorChangeTimer = nil
}
}
배경색이 변하는 시간을 바꾸고 싶다면 withTimeInterval의 시간(초) 바꾸기
AutoLayout
모든 기기의 방향까지 고려해서 거의 비슷한 디자인 나오도록 하는 것
Alignment
화면 정중앙으로 오게 하고 싶으면 Horizontally in Container 0하고 체크, Vertically in Container 0하고 체크
Constraints 생김
장점 | 단점 |
다양한 화면 크기 지원: Auto Layout을 사용하면 다양한 iPhone과 iPad의 화면 크기에 자동으로 맞춰져 레이아웃이 조정됩니다. | 복잡성 증가: 많은 제약을 설정해야 할 경우, 레이아웃이 복잡해지고 관리하기 어려울 수 있습니다. |
유연성: 화면 회전, 다크 모드, 다른 해상도에서도 레이아웃이 자동으로 조정됩니다. | 디버깅 어려움: 제약이 잘못 설정되면, 원하는 대로 화면이 표시되지 않거나 충돌할 수 있어 디버깅이 복잡할 수 있습니다. |
자동 크기 조정: 화면의 크기에 맞춰 자동으로 크기나 위치를 조정해줍니다. | 성능 문제: 복잡한 제약이 많아지면, 앱 성능에 영향을 줄 수 있습니다. |
인터페이스 변경 용이: 디자인을 변경할 때 Auto Layout을 사용하면 코드 수정 없이 인터페이스를 쉽게 조정할 수 있습니다. | 학습 곡선: Auto Layout을 처음 배우는 사람에게는 제약의 개념과 설정 방법이 어려울 수 있습니다. |
다양한 화면에서의 일관성: 다양한 기기에서 일관성 있게 UI를 유지할 수 있습니다. | 제약 충돌: 잘못된 제약 설정으로 인해 UI 요소들이 예상과 다르게 배치될 수 있습니다. |
ChatGPT로 iOS 전광판 앱 만들기
1. 스토리보드로 기본 UI 구성
- UILabel 추가:
- UILabel을 사용하여 전광판에 표시할 텍스트를 설정합니다.
- Main.storyboard에서 UILabel을 드래그하여 뷰에 배치합니다.
- 텍스트가 스크롤되도록 하기 위해 텍스트의 크기와 위치를 적절히 설정합니다.
- 뷰 컨트롤러 설정:
- ViewController를 선택하고, 스토리보드에서 UILabel을 IBOutlet으로 연결할 준비를 합니다.
2. 코드 작성
ViewController.swift에서 텍스트가 스크롤되는 애니메이션을 추가합니다.
import UIKit
class ViewController: UIViewController {
// Storyboard에서 연결된 UILabel
@IBOutlet weak var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// 배경 색을 검은색으로 설정
view.backgroundColor = .black
// 레이블 설정
textLabel.textColor = .white
textLabel.font = UIFont.systemFont(ofSize: 30)
textLabel.sizeToFit()
// 텍스트가 화면 오른쪽에서 시작하도록 설정
textLabel.frame.origin = CGPoint(x: self.view.frame.width, y: self.view.frame.height / 2)
// 텍스트 애니메이션 시작
startScrolling()
}
func startScrolling() {
// 애니메이션을 사용해 텍스트가 왼쪽으로 이동하도록 설정
UIView.animate(withDuration: 10.0, delay: 0, options: [.repeat, .curveLinear], animations: {
// 텍스트가 화면을 벗어날 때까지 왼쪽으로 이동
self.textLabel.frame.origin.x = -self.textLabel.frame.width
}, completion: nil)
}
}
2.1 스토리보드 설정
- Main.storyboard에서 UIViewController를 선택하고, UILabel을 추가합니다.
- 텍스트를 "Hello, 전광판 앱!"과 같은 기본 텍스트로 설정합니다.
- UILabel의 크기와 위치를 적절하게 설정하여 전광판처럼 보이게 합니다.
- Auto Layout을 활용하여 화면 크기에 맞게 UILabel이 조정되도록 설정합니다.
- IBOutlet 연결:
- UILabel을 코드에서 제어할 수 있도록 IBOutlet을 만듭니다.
- Ctrl + 드래그를 사용하여 ViewController.swift의 클래스에 UILabel을 연결합니다.
2.2 ViewController.swift 코드
이제 애니메이션을 적용할 코드 작성입니다.
import UIKit
class ViewController: UIViewController {
// Storyboard에서 연결된 UILabel
@IBOutlet weak var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// 배경 색을 검은색으로 설정
view.backgroundColor = .black
// 레이블 설정
textLabel.textColor = .white
textLabel.font = UIFont.systemFont(ofSize: 30)
textLabel.sizeToFit()
// 텍스트가 화면 오른쪽에서 시작하도록 설정
textLabel.frame.origin = CGPoint(x: self.view.frame.width, y: self.view.frame.height / 2)
// 텍스트 애니메이션 시작
startScrolling()
}
func startScrolling() {
// 애니메이션을 사용해 텍스트가 왼쪽으로 이동하도록 설정
UIView.animate(withDuration: 10.0, delay: 0, options: [.repeat, .curveLinear], animations: {
// 텍스트가 화면을 벗어날 때까지 왼쪽으로 이동
self.textLabel.frame.origin.x = -self.textLabel.frame.width
}, completion: nil)
}
}
3. 애니메이션 설명
- UIView.animate를 사용하여 UILabel이 화면을 벗어날 때까지 왼쪽으로 스크롤되도록 설정합니다.
- 애니메이션의 지속 시간을 10초로 설정하고, 무한 반복(.repeat) 및 선형 애니메이션(.curveLinear) 옵션을 적용하여 부드럽게 흐르도록 합니다.
4. 전체 흐름
- 스토리보드에서 UILabel을 추가하고, IBOutlet을 연결합니다.
- ViewController.swift에서 텍스트가 왼쪽으로 흐르도록 애니메이션을 설정합니다.
- 텍스트가 화면을 넘어가면 다시 오른쪽에서 시작하도록 반복 애니메이션을 적용합니다.
5. 결과
앱을 실행하면, UILabel이 화면에서 오른쪽에서 왼쪽으로 부드럽게 흐르며 전광판처럼 보이게 됩니다.
추가 기능 (선택 사항)
- 텍스트 색상, 크기, 속도 등을 조정할 수 있는 슬라이더나 버튼을 추가하여 사용자가 직접 설정할 수 있게 할 수 있습니다.
전광판 앱
//
// ViewController.swift
// Display
//
// Created by redmist on 3/19/25.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var label: UILabel!
@IBAction func displayText(_ sender: UIButton) {
label.text = textField.text
startScrolling()
}
func startScrolling() {
UIView.animate(withDuration: 10, delay: 0, options: [.curveLinear, .repeat], animations: {
self.label.center.x -= self.view.bounds.width
}, completion: nil)
}
}
출처: iOS 프로그래밍 실무 강의자료