안녕하세요! 피피아노입니다 🎵
이번 포스팅에서는 저번 포스팅에 이어서 SwiftUI와 UIKit을 통합하는 방법에 대해서 정리해보겠습니다.
저번 포스팅이 궁금하신 분들은 여기를 참고해주세요!
그럼 바로 시작하겠습니다!
프로젝트 생성
저번 포스팅에서는 개념에 대해서 다뤄봤으니 이번 포스팅에서는 프로젝트에서 직접 해보겠습니다.
먼저 스토리보드로 시작하는 HostingControllerTest 라는 프로젝트를 하나 만들어주겠습니다.
SwiftUI 콘텐트 뷰 추가
생성을 했다면 해당 프로젝트 파일 안에 SwiftUI View 파일을 추가해주겠습니다.
추가하는 방법은 File > New File from Template... 메뉴 옵션을 선택해서 SwiftUI View 템플릿을 선택하고 생성해주면 됩니다.
그리고 코드를 살짝 수정해주겠습니다.
import SwiftUI
struct SwiftUIView: View {
var test: String
var body: some View {
VStack {
Text(test)
HStack {
Image(systemName: "Apple")
Text("This is a SwiftUI test View")
}
}
}
}
#Preview {
SwiftUIView(test: "Sampele Text")
}
자 이제 기본적인 세팅은 끝났으니 이제 스토리보드로 넘어가겠습니다.
StoryBoard 세팅
Main.storyboard 파일을 선택하고 Navigation Controller를 하나 추가해주겠습니다.
추가하는 방법은 아래 이미지처럼 View Controller을 클릭하고 Editor > Embed In > Navigation Controller 메뉴를 선택해주시면 됩니다.
그럼 이렇게 화면이 구성되게 됩니다.
그리고 버튼을 하나 추가해서 이 버튼을 누르면 SwiftUI View를 포함하는 새로운 뷰 컨트롤러가 표시되게 해주겠습니다.
버튼 추가가 완료 되었다면, 라이브러리 패널에서 Hosting View Controller를 추가해주겠습니다.
그리고 버튼을 Hosting Controller에 연결을 해줘서 segue를 추가해주겠습니다.
연결해주고 나타나는 화면에서 Show를 선택해주시면 됩니다.
Segue 액션 구성하기
이제 버튼을 누르면 SwiftUI View가 호스팅 컨트롤러에 로드가 되도록 구성을 해주겠습니다.
Xcode에서 Editor > Assistant 메뉴를 선택해주고 어시스턴트 에디터 패널이 표시되게 해줍니다.
어시스트 에디터 패널이 나타나면 ViewController 파일의 내용이 표시되도록 해주겠습니다.
그리고 View Controller와 Hosting Controller 사이에 있는 segue을 클릭하고 ViewDidLoad() 아래로 드래그앤드랍을 해서 연결을 해주겠습니다.
그리고 소스를 수정해주겠습니다.
import UIKit
import SwiftUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBSegueAction func showSwiftUI(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: SwiftUIView(test: "Hello, World!"))
}
}
그리고 실행을 해보면 버튼을 눌렀을 때 SwiftUI View로 넘어가는 것을 확인할 수 있습니다.
코드로 통합하기
다음 통합 방식으로 SwiftUI View를 View Controller의 레이아웃에 포함을 시킬 수도 있습니다.
Xcode에서 ViewController.swift 파일을 편집해주겠습니다.
해당 파일에서 viewDIdLoad() 메서드를 아래처럼 수정해주겠습니다.
override func viewDidLoad() {
super.viewDidLoad()
let swiftUIController = UIHostingController(rootView: SwiftUIView(test: "Hello, World!!!!"))
addChild(swiftUIController)
swiftUIController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(swiftUIController.view)
swiftUIController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
swiftUIController.view.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
swiftUIController.didMove(toParent: self)
}
이렇게 코드를 수정해주면 먼저, SwiftUI 뷰를 감싸는 UIHostingController를 생성합니다. 이 컨트롤러는 SwiftUI의 선언적 UI를 UIKit의 명령형 환경으로 변환하는 브릿지 역할을 합니다.
다음으로, 생성된 UIHostingController를 현재의 UIViewController에 자식으로 추가합니다. 이는 뷰 계층 구조를 올바르게 설정하고 생명주기 이벤트가 적절히 전파되도록 보장합니다.
SwiftUI 뷰의 레이아웃을 UIKit 환경에 맞게 조정하기 위해, 자동 크기 조정 마스크를 제약 조건으로 변환하는 기능을 비활성화합니다. 이후 SwiftUI 뷰를 UIKit 뷰 계층 구조에 추가하고, 중앙 정렬을 위한 Auto Layout 제약 조건을 설정합니다.
마지막으로, 자식 뷰 컨트롤러가 부모에게 추가되었음을 시스템에 알립니다.
그리고 실행을 해보면 아래처럼 버튼 아래에 SwiftUI View가 나타나게 됩니다.
마무리
통합하는 과정을 아예 몰랐을 때는 UIKit 따로 SwiftUI 따로 프로젝트를 만들어야 하는 줄 알았는데 통합을 배우니까 뭔가 작업할 수 있는 영역의 폭이 확 넓어진 느낌이 들어서 너무 좋은 것 같습니다!
아직은 완전 초보 단계라 이 기능을 얼마나 쓰게 될지는 모르겠지만 그래도 뭔가를 할 수 있는 폭이 넓어졌으니 만족!!
감사합니다.
잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!
궁금하신 부분은 댓글로 질문 부탁드립니다!
'Apple > SwiftUI' 카테고리의 다른 글
[SwiftUI] 애니메이션과 전환 간단하게 알아보기 (8) | 2024.10.02 |
---|---|
[SwiftUI] SwiftUI와 UIKit 통합하기 (1/2) (5) | 2024.09.14 |
[SwiftUI] @AppStorage와 @SceneStorage 프로퍼티 래퍼 이해하기 (6) | 2024.09.11 |
[SwiftUI] Property Wrapper 알아보기 (0) | 2024.07.29 |
[SwiftUI] AVFoundation 톺아보기 (2) | 2024.07.15 |