Canvas는 시뮬레이터를 실행하지 않고 SwiftUI View를 실시간으로 표시하는 대화형 Xcode 미리보기 편집기입니다. Canvas는 코드가 변경될 때마다 자동으로 업데이트되며 제스처, 내비게이션 및 다크 모드를 지원합니다. Apple Developer Documentation(2026)에 따르면 Canvas는 별도의 렌더러 프로세스 PreviewProviderExtension을 사용하여 전체 프로젝트를 다시 컴파일하지 않고도 코드를 편집하고 즉시 결과를 확인할 수 있습니다. SwiftUI에 대한 자세한 내용은 SwiftUI 문서에서 확인하세요.
핵심 요점
Canvas는 Xcode에 내장된 미리보기 편집기로, SwiftUI와 함께 Xcode 11에서 처음 도입되었습니다. 코드 옆 편집기의 오른쪽 패널에 위치하며 현재 SwiftUI View의 라이브 미리보기를 표시합니다. Canvas는 실시간으로 작동합니다. 코드의 모든 변경 사항이 수동 재컴파일 없이 즉시 미리보기에 반영됩니다.
아키텍처적으로 Canvas는 Xcode가 Canvas를 열 때 시작하는 별도의 프로세스(Preview Provider Extension)입니다. 이 프로세스는 컴파일된 PreviewProvider를 로드하고 Metal을 통해 결과를 렌더링하여 편집기 패널에 표시합니다. PreviewProvider가 구현되지 않은 경우 Canvas는 “Preview paused — No preview provider found” 플레이스홀더를 표시합니다.
Canvas 인터페이스에는 기기 선택, 방향, 색상 구성 및 배율 옵션이 있는 도구 모음이 포함되어 있습니다. Live Preview, Selectable 및 Embed In Diagram 버튼은 상호작용 모드를 전환합니다. Canvas는 분할 보기를 지원합니다. 동일한 작업 공간에서 다른 파일에 대해 여러 Canvas를 열 수 있습니다.
| Canvas 요소 | 목적 |
|---|---|
| 기기 선택기 | 미리보기할 기기 선택(iPhone, iPad, Apple Watch) |
| 방향 전환 | 세로/가로 전환(iOS, iPadOS) |
| 색상 구성 | 라이트/다크 테마 |
| Dynamic Type 슬라이더 | 접근성 테스트를 위한 글꼴 배율 |
| Live Preview | 제스처 지원이 포함된 대화형 모드 |
| 선택 모드 | 인터페이스 요소 검사 |
Live Preview는 미리보기를 대화형으로 만드는 Canvas의 핵심 기능입니다. 이 모드에서 Canvas는 별도의 프로세스에서 View를 렌더링하고 제스처(탭, 스와이프, 스크롤)를 SwiftUI 런타임으로 다시 전달합니다. 사용자는 시뮬레이터를 실행하지 않고도 버튼을 누르고, 텍스트 필드를 채우고, 내비게이션을 테스트할 수 있습니다.
SwiftUI는 실제 기기와 동일한 이벤트 시스템을 통해 Canvas에서 제스처를 처리합니다. 차이점은 성능에 있습니다. Canvas는 Metal을 통한 소프트웨어 렌더링을 사용하는 반면, 시뮬레이터는 호스트 그래픽을 사용합니다. 즉, Canvas의 복잡한 애니메이션이 더 느리게 실행되거나 시각적으로 다르게 보일 수 있습니다.
Canvas 업데이트는 세 단계로 이루어집니다. 먼저 Xcode가 파일 변경을 감지하고 변경된 PreviewProvider만 증분 컴파일합니다. 그런 다음 새 바이너리 모듈이 PreviewProviderExtension 프로세스에 로드됩니다. 마지막으로 SwiftUI가 View를 다시 생성하고 Metal을 통해 렌더링합니다. 전체 주기는 View 복잡성에 따라 0.5~2초가 소요됩니다.
struct TappableButton: View {
@State private var count = 0
var body: some View {
Button("Tapped \(count) times") {
count += 1
}
.buttonStyle(.borderedProminent)
}
}
struct TappableButton_Previews: PreviewProvider {
static var previews: some View {
TappableButton()
}
}
상호작용성: Live Preview가 실행 중이면 Canvas의 버튼이 실제 버튼처럼 작동합니다. 탭할 때마다 카운터가 증가하고 누름 애니메이션이 표시됩니다. 이를 통해 시뮬레이터 없이 버튼 로직을 테스트할 수 있습니다.
Canvas의 기본 설정은 Editor → Canvas 메뉴 또는 Canvas 도구 모음 버튼을 통해 사용할 수 있습니다. 주요 옵션으로는 기기 선택, 방향, 다크 테마 및 Dynamic Type 배율이 있습니다. 영구 설정의 경우 코드에서 PreviewProvider 수정자를 사용하세요.
고급 설정에는 다음이 포함됩니다: Auto Activate Preview — SwiftUI 파일을 열 때 자동 Canvas 활성화; Live Preview — 제스처 모드; Draw Live Edges — View 경계 표시; Show Preview Sizes — 미리보기 영역 크기. Xcode는 이러한 설정을 작업 공간/프로젝트 파일에 이식 가능하게 저장합니다.
프로그래매틱 구성은 Canvas를 더 정밀하게 제어할 수 있습니다. 미리보기에 적용된 수정자는 도구 모음 설정을 재정의하고 코드에 저장되므로 모든 팀 구성원이 git을 통해 확인할 수 있습니다.
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
.previewDevice("iPhone 16 Pro")
.previewLayout(.device)
.preferredColorScheme(.dark)
.dynamicTypeSize(.xxxLarge)
.previewDisplayName("Dark + XL Text")
}
}
previewLayout을 .device와 함께 사용하면 전체 기기 화면이 표시되고, .sizeThatFits는 콘텐츠에 맞게 크기가 조정된 컴팩트 미리보기를 표시합니다. 위젯 및 작은 구성 요소에는 .sizeThatFits를 사용하세요. 편집기에서 공간을 절약할 수 있습니다.
예제 1: 적응형 테스트. 여러 기기와 색상 구성으로 ForEach를 사용하여 모든 화면에서 인터페이스가 잘 표시되는지 확인하세요. Canvas는 모든 미리보기를 동시에 업데이트하므로 시뮬레이터를 시작하기 전에 레이아웃 문제를 발견할 수 있습니다.
예제 2: 데이터가 있는 미리보기. 동적 콘텐츠(목록, 프로필, 카드)를 표시하는 View의 경우 미리보기에서 서로 다른 데이터로 여러 인스턴스를 만드세요. 이는 시뮬레이터에서 화면 간 전환 및 데이터 입력보다 빠릅니다.
미리보기 그룹은 Group 또는 ForEach를 통해 하나의 패널에 모든 구성 요소 상태를 표시할 수 있습니다. 목록의 경우 특히 편리합니다. 빈 목록, 로딩, 오류 및 채워진 목록이 동시에 표시됩니다.
struct LoadingStateView: View {
let state: LoadingState
var body: some View {
switch state {
case .loading:
ProgressView()
case .loaded(let items):
List(items, id: \.self) { Text($0) }
case .error(let message):
Text(message).foregroundColor(.red)
}
}
}
struct LoadingStateView_Previews: PreviewProvider {
static var previews: some View {
Group {
LoadingStateView(state: .loading)
.previewDisplayName("Loading")
LoadingStateView(state: .loaded(["Item 1", "Item 2"]))
.previewDisplayName("Loaded")
LoadingStateView(state: .error("Failed to load"))
.previewDisplayName("Error")
}
}
}
Canvas와 시뮬레이터는 서로를 대체하는 것이 아니라 보완합니다. Canvas는 레이아웃 중 빠른 반복에 이상적입니다. 즉각적인 피드백으로 코드를 편집할 수 있습니다. 시뮬레이터는 최종 확인에 필요합니다. 실제 성능, 사용자 정의 제스처, 시스템 알림 및 하드웨어 기능(카메라, 센서)과의 통합을 테스트합니다.
WWDC 2024에 따르면 Apple은 Canvas를 초기 개발 단계의 도구로, 시뮬레이터를 통합 테스트용 도구로 포지셔닝합니다. UI 개발 시간의 60%는 Canvas에서, 40%는 시뮬레이터 또는 기기에서 테스트하는 데 사용하는 것이 좋습니다.
| 특성 | Canvas | 시뮬레이터 |
|---|---|---|
| 업데이트 속도 | 0.5~2초(증분) | 10~60초(전체 빌드) |
| 제스처 | 기본(탭, 스크롤) | 모두(핀치, 회전, 3D Touch) |
| 카메라/자이로스코프 | 지원되지 않음 | 시뮬레이션 |
| 애니메이션 | 제한됨 | 전체 |
| 푸시 알림 | 지원되지 않음 | 지원됨 |
| 네트워크 | Xcode 프로세스를 통해 | 전체 네트워크 스택 |
권장 사항: Canvas에서 디자인하고 시뮬레이터에서 테스트하세요. 버튼 및 내비게이션의 제스처 로직에는 Live Preview를 사용하되, 애니메이션, 네트워크 요청 및 하드웨어 기능의 최종 테스트는 시뮬레이터 또는 실제 기기에서 수행하세요.
팁 1: 선택 모드 사용. 선택 모드(커서 아이콘)에서는 미리보기의 모든 요소를 클릭하여 검사기에서 해당 계층 구조, 수정자 및 프레임을 볼 수 있습니다. 이는 레이아웃 디버깅에 유용합니다. print 문 없이 패딩, 오프셋 및 요소 크기를 즉시 확인할 수 있습니다.
팁 2: Embed In Diagram. Canvas는 요소를 그룹화할 수 있습니다. 두 개 이상의 View를 선택하고 Embed In Diagram을 클릭하면 Canvas가 VStack/HStack/ZStack을 만들고 코드를 자동으로 재구성합니다. 이렇게 하면 수동으로 괄호를 입력하지 않고도 복잡한 계층 구조를 빠르게 만들 수 있습니다.
팁 3: Canvas 미리보기 캐시 지우기. Canvas 업데이트가 중단되면 Product → Preview Cache를 지우세요. Xcode는 캐시된 PreviewProvider 바이너리를 삭제하고 처음부터 다시 빌드합니다. 이렇게 하면 Canvas 멈춤 문제의 90%가 해결됩니다.
Canvas가 느린 경우는 일반적으로 미리보기 수가 과도하기 때문입니다. 복잡한 View의 경우 6~8개의 그룹 대신 하나의 미리보기만 사용하세요. 제스처가 없는 View에서는 Live Preview를 끄세요. 정적 모드가 더 빠르게 렌더링됩니다. PreviewProvider가 실제 네트워크 요청 대신 모의 데이터를 사용하는지 확인하세요.
// Quick debug: minimal preview
struct ComplexView_Previews: PreviewProvider {
static var previews: some View {
ComplexView()
.previewLayout(.sizeThatFits) // compact mode
}
}
previewLayout(.sizeThatFits)는 기기 테두리 없이 View 콘텐츠만 렌더링하므로 가장 빠른 Canvas 모드입니다. 일상적인 레이아웃 작업에 이 모드를 사용하고 최종 확인 시에만 .device를 활성화하세요.
자주 묻는 질문
가장 흔한 이유는 현재 View에 PreviewProvider가 없기 때문입니다. Canvas는 previews 속성에서 View를 반환하는 PreviewProvider 프로토콜 구현이 필요합니다. 다른 이유: 코드의 컴파일 오류, DerivedData 문제 또는 PreviewProviderExtension 프로세스가 시작되지 않음.
네, Xcode는 Product → Preview → Debug Preview를 통한 미리보기 디버깅을 지원합니다. 활성화 후 View 코드의 중단점이 Canvas 렌더링 시 트리거됩니다. 이를 통해 런타임 변수 값을 분석하고 표시 로직을 확인할 수 있습니다.
Canvas는 UIViewRepresentable 및 UIViewControllerRepresentable을 통해 UIKit 구성 요소를 지원합니다. 그러나 일부 구성 요소는 렌더링되지 않습니다: MapKit, WebView, AVPlayer를 통한 비디오, 사용자 정의 Metal/GLKit 뷰. Canvas는 하드웨어 기능을 에뮬레이션하지 않으므로 카메라와 센서를 사용할 수 없습니다.
Group에서 미리보기 수를 줄이고(최대 3~4개), .device 대신 previewLayout(.sizeThatFits)을 사용하고, 제스처가 없는 View에서는 Live Preview를 끄세요. Product → Preview Cache를 지우세요. PreviewProvider가 네트워크 요청을 하지 않는지 확인하고 모의 데이터를 사용하세요.
Canvas는 릴리스 IPA 크기에 영향을 미치지 않습니다. PreviewProvider 코드는 Debug 구성에서만 컴파일됩니다. 개발 중에 Canvas는 DerivedData에 최대 100~200MB의 캐시를 추가하며, 이는 Xcode에서 자동으로 관리됩니다. 정기적으로 DerivedData를 정리하면 공간을 확보할 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.