SA성아 2025. 3. 19. 16:45

ChatGPT로  iOS 무드등 앱 만들기


무드등 iOS 앱 사전 계획서

1. 프로젝트 개요

  • 앱 이름: (추후 결정)
  • 앱 유형: 무드등 및 조명 컨트롤 앱
  • 대상 사용자: 감성적인 조명을 활용하고 싶은 일반 사용자, 수면 조명이 필요한 사용자

2. 주요 기능

  1. 기본 무드등 기능
    • 다양한 컬러 설정 (RGB 색상 선택)
    • 밝기 조절 기능
    • 타이머 기능 (지정된 시간 후 자동 종료)
  2. 프리셋 & 테마
    • 감성적인 조명 테마 제공 (예: 로맨틱, 집중, 숙면 등)
    • 사용자가 직접 커스텀 테마 생성 및 저장 가능
  3. 음악 & 조명 연동
    • 음악을 재생하면 리듬에 맞춰 색상이 변하는 기능
    • 앱 내 사운드스케이프 (빗소리, 자연의 소리 등) 제공
  4. 위젯 & 단축어 지원
    • 홈 화면 위젯에서 간단한 조작 가능
    • Siri 단축어 연동으로 음성 명령 실행
  5. 수면 모드
    • 서서히 밝아지는 기상 조명
    • 취침 전 점점 어두워지는 기능
  6. 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)를 관리하는 핵심 클래스입니다. 앱이 실행되거나 종료될 때 필요한 작업을 처리합니다.


📌 주요 역할

  1. 앱이 실행될 때 (didFinishLaunchingWithOptions)
    • 초기 설정을 수행하는 메서드 (예: Firebase 설정, UserDefaults 로드 등)
    • return true를 반환하면 앱이 정상 실행됨
  2. 새로운 화면(Scene)이 생성될 때 (configurationForConnecting)
    • iOS 13부터 추가된 멀티 윈도우(Scene) 지원을 위한 설정
    • 기본적으로 "Default Configuration"을 반환하여 앱이 정상 작동하도록 함
  3. 사용자가 Scene을 닫았을 때 (didDiscardSceneSessions)
    • 불필요한 리소스를 해제할 수 있는 메서드

📌 실행 흐름

  1. 앱 실행 → didFinishLaunchingWithOptions 실행
  2. 새로운 Scene 생성 → configurationForConnecting 실행
  3. 사용자가 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 구성

  1. UILabel 추가:
    • UILabel을 사용하여 전광판에 표시할 텍스트를 설정합니다.
    • Main.storyboard에서 UILabel을 드래그하여 뷰에 배치합니다.
    • 텍스트가 스크롤되도록 하기 위해 텍스트의 크기와 위치를 적절히 설정합니다.
  2. 뷰 컨트롤러 설정:
    • 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 스토리보드 설정

  1. Main.storyboard에서 UIViewController를 선택하고, UILabel을 추가합니다.
    • 텍스트를 "Hello, 전광판 앱!"과 같은 기본 텍스트로 설정합니다.
    • UILabel의 크기와 위치를 적절하게 설정하여 전광판처럼 보이게 합니다.
    • Auto Layout을 활용하여 화면 크기에 맞게 UILabel이 조정되도록 설정합니다.
  2. 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. 전체 흐름

  1. 스토리보드에서 UILabel을 추가하고, IBOutlet을 연결합니다.
  2. ViewController.swift에서 텍스트가 왼쪽으로 흐르도록 애니메이션을 설정합니다.
  3. 텍스트가 화면을 넘어가면 다시 오른쪽에서 시작하도록 반복 애니메이션을 적용합니다.

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 프로그래밍 실무 강의자료