SwiftUI와 UIKit 통합하기

2 분 소요

SwiftUI가 도입되기 전 개발된 앱은 UIKit과 UIKit 기반의 프레임워크를 사용
기존의 프로젝트 코드 + 새로운 SwiftUI 앱 기능 통합
-> UIHostingController 사용


호스팅 컨트롤러의 개요

호스팅 컨트롤러(Hosting Controller)

  • UIHostingController 클래스 형태
  • UIViewController의 하위 클래스
  • 기존의 UIKit 기반의 프로젝트에 통합될 수 있도록 SwiftUI 뷰를 감싸는 것
    • SwiftUI 뷰를 전체 화면으로 처리
    • 컨테이너 뷰에 호스팅 컨트롤러를 내장하여 개별 컴포넌트로 취급

    • 스토리보드 사용
    • 코드 사용
      1. 호스팅된 SwiftUI 뷰를 사용자에게 표시
         let swiftUIController = UIHostingController(rootView: SwiftUIView())
         present(swiftUIController, animated: true, completion: nil)
        
      2. 호스팅된 SwiftUI 뷰를 기존 UIViewController의 레이아웃에 직접 포함
         let swiftUIController = UIHostingController(rootView: SwiftUIView())
                    
         addChild(swiftUIController)
         view.addSubview(swiftUIController.view)
                    
         swiftUIController.didMove(toParent: self)
        

UIHostingController 예제 프로젝트

User Interface - Stroyboard
3가지 통합 방법

SwiftUI 콘텐트 뷰 추가하기

import SwiftUI

struct SwiftUIView: View {
    
    var text: String
    
    var body: some View {
        VStack {
            Text(text)
            HStack {
                Image(systemName: "smiley")
                Text("This is a SwiftUI View")
            }
        }
        .font(.largeTitle)
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView(text: "Sample Text")
    }
}

스크린샷 2022-06-20 오전 11 21 39

스토리보드 준비하기

뷰 컨트롤러를 내비게이션 컨트롤러에 포함(화면 이동)

스크린샷 2022-06-20 오전 11 39 15

View Controller 버튼 클릭
Editor -> Embed In -> Navigation Controller

스크린샷 2022-06-20 오전 11 45 04

첫 번째 SwiftUI 통합

버튼 클릭시 SwiftUI View를 포함하는 새로운 뷰 컨트롤러가 표시

스크린샷 2022-06-20 오후 12 01 57

라이브러리 패널을 통해 버튼 추가
텍스트 편집
Resolve Auto Layout Issues -> Reset to Suggested Contstraints
(추천 제약으로 재설정 - 버튼 위치 고정)


호스팅 컨트롤러 추가하기

스크린샷 2022-06-20 오후 12 03 45

라이브러리 패널을 통해 Hosting View Controller 추가
버튼을 Hosting Controller로 드래그하여 segue 추가
Show 메뉴 선택
실행시 호스팅 뷰 컨트롤러는 검정색 백그라운드 표시 (아무 컨텐트x)


Segue 액션 구성하기

IBSegueAction을 추가하여 버튼이 클릭되면 SwiftUI 뷰가 호스팅 컨트롤러에 로드

스크린샷 2022-06-20 오후 12 20 24

어시스턴트 에디터(Assistant Editor) 패널 표시 (Editor -> Assistant)
뷰 컨트롤러와 호스팅 컨트롤러 사이에 있는 segue 라인 드래그

import SwiftUI
.
.
@IBSegueAction func showSwiftUIVIew(_ coder: NSCoder) -> UIViewController? {
    return UIHostingController(coder: coder,
                                rootView: SwiftUIView(text: "Integration One"))
}

두 번째 화면 표시

두 번째 SwiftUI 통합

컨테이너 뷰가 뷰 컨트롤러에 추가되어 UIKit 컴포넌트와 함께 SwiftUI 뷰에 포함

스크린샷 2022-06-20 오후 2 24 53

라이브러리 패널에서 Container View 추가
Resolve Auto Layout Issues -> Reset to Suggested Contstraints
상단의 추가된 View Controller는 삭제
라이브러리 패널에서 Hosting View Controller 상단에 추가
Container View와 호스팅 컨트롤러를 segue -> Embed

IBSegueAction 추가

@IBSegueAction func embedSwiftUIView(_ coder: NSCoder) -> UIViewController? {
    return UIHostingController(coder: coder, rootView: SwiftUIView(text: "Integration Two"))
}

스크린샷 2022-06-20 오후 2 33 51

세 번째 SwiftUI 통합

코드로 SwiftUI 포함하기

override func viewDidLoad() {
    super.viewDidLoad()

    let swiftUIController = UIHostingController(rootView: 
                                             SwiftUIView(text: "Integration Three")) // 인스턴스 생성
        
    addChild(swiftUIController) // 뷰 컨트롤러의 자식으로 추가
    swiftUIController.view.translatesAutoresizingMaskIntoConstraints = false 
    // 추가하는 컨스트레인트는 자동 컨스트레인트와 충돌x
        
    view.addSubview(swiftUIController.view) //호스팅 컨트롤러의 자식 UIView가 뷰 컨트롤러의 하위 뷰로 추가
        
    swiftUIController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    swiftUIController.view.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    // 화면 중앙에 배치    
        
    swiftUIController.didMove(toParent: self) // 이동시 UIKit에 알리는 이벤트 실행
}

스크린샷 2022-06-20 오후 2 31 14

카테고리:

업데이트: