Dynamic Island는 iPhone 14 Pro 및 모든 iPhone 15/16 상단에 있는 인터랙티브 영역으로, 알림, 백그라운드 활동 및 시스템 표시기를 하나의 동적 영역에 통합합니다. 기존 노치와 달리 Dynamic Island는 현재 컨텍스트에 따라 모양과 크기가 변경됩니다. Apple(WWDC 2024)에 따르면 사용자는 평균적으로 하루에 12회 Dynamic Island와 상호작용합니다 — 탭, 길게 누르기 및 ActivityKit을 사용한 Live Activities를 통해. iOS의 애니메이션에 대한 자세한 내용은 Corner Radius 문서를 참조하세요.
주요 내용
Dynamic Island는 Apple의 소프트웨어-하드웨어 솔루션을 기반으로 한 인터랙티브 영역으로, 2022년 9월 iPhone 14 Pro와 함께 출시되었습니다. 물리적으로는 OLED 픽셀로 둘러싸인 알약 모양의 컷아웃으로, 동적으로 색상과 모양이 변경됩니다. Apple은 카메라 및 Face ID용 하드웨어 컷아웃과 주변 검은 영역의 소프트웨어 렌더링을 결합하여 «살아있는» 섬의 환상을 만듭니다.
Dynamic Island의 주요 목표는 시스템 알림과 활성 콘텐츠 간의 격차를 해소하는 것입니다. 알림이 화면 중앙(Android처럼)이나 상단 배너(이전 iOS처럼)로 표시되는 대신, Dynamic Island가 이를 하드웨어 영역에 직접 통합합니다. 이는 주의 산만을 줄이고 통합된 공간감을 만듭니다.
Apple 데이터(iOS 17 채택 통계, 2024)에 따르면 Dynamic Island는 활성 iPhone의 38%에서 사용 가능합니다. iPhone 15(2023)부터 기본 모델을 포함한 라인업의 모든 모델에 Dynamic Island가 탑재되었습니다. iOS 18에서 Apple은 Live Activities API를 확장하여 Dynamic Island에서 직접 카운트다운 타이머 및 스포츠 점수 지원을 추가했습니다.
Dynamic Island는 iPhone 14 Pro, iPhone 14 Pro Max, iPhone 15, iPhone 15 Plus, iPhone 15 Pro, iPhone 15 Pro Max, iPhone 16, iPhone 16 Plus, iPhone 16 Pro, iPhone 16 Pro Max에서 사용 가능합니다. iPad에서는 Dynamic Island를 사용할 수 없습니다. Dynamic Island 개발에는 Xcode 14.1+ 및 iOS 16.1+가 필요합니다.
Dynamic Island는 컴팩트, 최소, 확장의 세 가지 표시 상태를 지원합니다. 상태 간 전환은 UIKit 애니메이션 및 Core Animation을 사용하여 애니메이션됩니다. 시스템 자체가 활동 우선순위를 관리합니다. 여러 앱이 동시에 콘텐츠를 표시하려고 하면 iOS는 마지막 활동의 시작 시간을 기준으로 대기열을 사용합니다.
| 상태 | 크기 | 콘텐츠 | 예시 |
|---|---|---|---|
| 컴팩트 | 49×18 pt | 앱 아이콘 + 시스템 아이콘 | 타이머, 음악, 통화 |
| 최소 | 최대 66×18 pt | 아이콘 + 짧은 텍스트 | 내비게이션 방향, 걸음 수 |
| 확장 | 최대 364×160 pt | 콘텐츠 포함 전체 위젯 | 스포츠 점수, 택시 상태 |
컴팩트 상태는 하나의 백그라운드 작업이 활성화된 경우 Dynamic Island의 표준 보기입니다. 왼쪽에 앱 아이콘, 오른쪽에 시스템 아이콘이 있는 둥근 알약 모양으로 나타납니다. 기본적으로 모든 Live Activities는 컴팩트 상태로 시작됩니다.
최소 상태는 두 개 이상의 작업이 동시에 활성화될 때 발생합니다. Dynamic Island가 카메라 왼쪽과 오른쪽에 두 개의 개별 요소로 «분할»됩니다. 최소 상태를 사용하면 택시 도착 시간과 현재 트랙 등 두 개의 독립적인 정보 소스를 표시할 수 있습니다.
확장 상태는 Dynamic Island를 길게 눌러 활성화됩니다. 이 모드에서는 사용자 정의 가능한 콘텐츠(제목, 설명, 진행 표시줄, 버튼)가 포함된 전체 위젯이 표시됩니다. 확장 상태는 스크롤 및 인터랙티브 요소를 지원합니다.
ActivityKit은 iOS 16.1에서 도입된 Swift 프레임워크로, 앱이 Dynamic Island 및 잠금 화면에 Live Activities를 게시할 수 있도록 합니다. ActivityKit은 ActivityView 및 ActivityAttributes를 기반으로 하는 아키텍처를 사용합니다. 전자는 콘텐츠 유형을 정의하고, 후자는 변경 가능한 데이터를 정의합니다. 이 프레임워크는 WidgetKit과 함께 작동하지만, 위젯과 달리 Live Activities는 앱을 열지 않고도 실시간으로 업데이트할 수 있습니다.
import ActivityKit
import SwiftUI
// 활동 속성 정의
struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var driverName: String
var distanceToArrival: Double
var estimatedMinutes: Int
}
var orderNumber: String
}
// Live Activity 시작
func startDeliveryActivity() {
let initialState = DeliveryAttributes.ContentState(
driverName: "알렉세이",
distanceToArrival: 3.5,
estimatedMinutes: 12
)
let attributes = DeliveryAttributes(orderNumber: "ORD-2024-8912")
let activity = try? Activity.request(
attributes: attributes,
contentState: initialState,
pushType: .token
)
}
Live Activities는 Dynamic Island용 SwiftUI 콘텐츠를 렌더링하는 ActivityView를 통해 업데이트됩니다. 시스템 자체가 Dynamic Island의 크기와 활동 수에 따라 사용할 템플릿(컴팩트, 최소 또는 확장)을 결정합니다. 콘텐츠를 업데이트하려면 activity.update(using: contentState)를 호출합니다. 종료하려면 — activity.end(dismissalPolicy: .immediate)를 호출합니다.
ActivityKit은 APNs(Apple Push Notification Service)를 통한 푸시 업데이트를 지원합니다. Live Activity를 시작할 때 pushToken을 요청하고 기기에서 앱을 실행하지 않고 서버에서 업데이트를 보낼 수 있습니다. 푸시 업데이트는 activity.pushToken 및 원격 Live Activity 시작을 위한 Activity.pushToStartToken을 통해 작동합니다.
// 푸시로 Live Activity 업데이트
func updateActivity(activity: Activity<DeliveryAttributes>) {
let updatedState = DeliveryAttributes.ContentState(
driverName: "알렉세이",
distanceToArrival: 1.2,
estimatedMinutes: 4
)
let alertConfiguration = AlertConfiguration(
title: "택배가 근처에 있습니다",
body: "알렉세이가 4분 후 도착합니다",
sound: .default
)
await activity.update(
using: updatedState,
alertConfiguration: alertConfiguration
)
}
AlertConfiguration은 중요한 업데이트(예: «택배 도착») 시 Dynamic Island 위에 알림을 표시하는 선택적 매개변수입니다. AlertConfiguration이 없으면 콘텐츠가 자동으로 업데이트되며, 진행 표시줄 및 타이머에 적합합니다.
노치는 전면 카메라, Face ID 센서 및 스피커가 포함된 iPhone X~13의 하드웨어 컷아웃입니다. 노치는 정적이며 크기와 모양이 변하지 않고 알림이 그 아래에 표준 배너로 표시됩니다. 반면 Dynamic Island는 컷아웃 주변의 픽셀을 사용하여 콘텐츠를 표시하여 하드웨어 요소를 인터페이스의 일부로 만듭니다.
| 기준 | Dynamic Island | 노치 |
|---|---|---|
| 상호작용 | 탭, 길게 누르기, 스와이프 지원 | 상호작용 불가 |
| 콘텐츠 적응 | 컨텍스트에 따라 모양 변경 | 정적, 콘텐츠가 노치 아래 |
| Live Activities | ActivityKit을 통한 내장 지원 | 없음 — 표준 알림만 |
| 멀티태스킹 | 두 개의 동시 활동(좌우) | 하나의 활동만 |
| 가용성 | iOS 16.1+, iPhone 14 Pro 이상 | iOS 11+, iPhone X~13 |
Apple Human Interface Guidelines(2025)에 따르면 Dynamic Island는 광고 또는 정적 콘텐츠의 영구 표시에 사용해서는 안 됩니다. Live Activities는 타이머, 배달, 스포츠, 음악, 내비게이션 등 명확한 라이프사이클을 가진 백그라운드 작업만을 대상으로 합니다. 이러한 규칙을 위반하면 App Store 검토에서 앱이 거부됩니다.
Dynamic Island는 엄격한 라이프사이클을 가지고 있습니다. 활동은 Activity.request()를 통한 요청으로 시작하고, 활성/일시 중지/업데이트됨 상태를 거치며 activity.end() 호출로 종료됩니다. 시스템은 메모리가 부족할 때(예: 카메라 실행 시) 활동을 강제 종료할 수 있습니다. 이 경우 앱은 ActivityActivityState.finished를 통해 알림을 받습니다.
제스처는 ActivityView 내의 SwiftUI 콘텐츠에 의해 처리됩니다. 표준 제스처: 컴팩트 상태 탭은 앱을 열고, 길게 누르면 확장 상태가 열리며, 아래로 스와이프하면 확장 상태가 닫힙니다. 사용자 정의 제스처는 활동 보기 내에서 SwiftUI 수정자(onTapGesture, onLongPressGesture)를 통해 추가됩니다.
시스템이 Live Activity를 종료하거나(사용자가 스와이프하여 제거) 앱이 리소스를 해제하기 위해 finished 상태를 처리해야 합니다. Activity.activityStateUpdates를 구독하고 완료 후 활동에 대한 로컬 참조를 제거하는 것이 좋습니다.
import ActivityKit
func observeActivityState(activity: Activity<DeliveryAttributes>) {
Task {
for await state in activity.activityStateUpdates {
switch state {
case .active:
print("Dynamic Island에서 활동 활성")
case .dismissed:
print("사용자가 활동을 숨김")
await activity.end(dismissalPolicy: .immediate)
case .finished:
print("시스템이 활동을 종료함")
cleanupResources()
@unknown default:
break
}
}
}
}
Apple 권장 사항(WWDC 2024, 세션 10146): 사용자의 주의가 필요하지 않은 상태를 표시하는 데 Dynamic Island를 사용하지 마십시오. 각 Live Activity에는 명확한 시작 및 종료 트리거가 있어야 합니다. UI 없이 백그라운드 업데이트를 위해서는 Live Activities 대신 Background Tasks를 사용하십시오.
자주 묻는 질문
Dynamic Island는 iPhone 14 Pro, 14 Pro Max 및 모든 iPhone 15 및 iPhone 16 모델(기본 버전 포함)에서 사용 가능합니다. 개발에는 iOS 16.1+ 및 Xcode 14.1이 필요합니다. 이전 모델(iPhone X~13)에서는 Live Activities를 지원하지 않는 정적 노치가 사용됩니다.
Dynamic Island는 콘텐츠를 가리지 않고 알림을 화면의 하드웨어 영역에 통합합니다. 일반 알림은 상단에 배너로 나타나며 몇 초 후에 사라집니다. Dynamic Island의 Live Activities는 몇 시간 동안 활성 상태를 유지하고 실시간으로 업데이트될 수 있습니다(배송 상태, 타이머, 음악).
APNs를 통한 푸시 업데이트를 사용하세요. Live Activity를 시작할 때 activity.pushToken을 호출하고 서버에 토큰을 보냅니다. 서버는 새 ContentState와 함께 APNs를 통해 업데이트 요청을 보냅니다. 대안으로 앱 내에서 activity.update(using:)를 통한 로컬 업데이트가 있습니다.
두 개의 Live Activities가 활성화되면 iOS가 자동으로 Dynamic Island를 두 개의 세그먼트로 분할합니다. 각 활동은 카메라 왼쪽과 오른쪽에 최소 상태로 표시됩니다. 세그먼트 중 하나를 길게 누르면 해당 앱에 대해서만 확장 상태가 열립니다.
확인 사항: (1) 앱의 Info.plist에 NSSupportsLiveActivities = YES가 있는지, (2) ActivityAttributes 및 ContentState가 Codable 및 Hashable을 구현하는지, (3) iOS 버전이 16.1+인지, (4) 기기가 Dynamic Island를 지원하는지. 시뮬레이터의 경우 Xcode에서 iPhone 14 Pro 이상을 사용하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.