[iOS] UIkit + SwiftUI 둘다 사용하기!

2024. 11. 27. 14:02·IOS - Swift/SwiftUI
반응형

이번에 솝커톤을 나가면서 경험했던 UIkit 과 SwiftUI를 둘다 사용해야 했던 상황에서 경험한 멀티모듈 사용법 정리

 

UIHostingController: UIKit에서 SwiftUI View를 사용하기

UIKit 기반 프로젝트에서 SwiftUI 뷰를 호스팅하는 데 사용됩니다.

  • 사용 예시:
    • SwiftUI로 만든 특정 뷰를 기존 UIKit 뷰 계층에 삽입할 때.
    • UIKit의 UIViewController나 UINavigationController 위에 SwiftUI 뷰를 추가할 수 있습니다.

동작 방식

SwiftUI 뷰를 UIKit에서 UIHostingController의 rootView로 설정하면, UIKit에서 SwiftUI 뷰를 렌더링합니다.

import UIkit
import SwiftUI

private func pushToQuestDetailView() {
    // 1. SwiftUI 뷰 생성과 동시에 클로저 전달
    let questDetailView = QuestDetailView(onPhotoTaken: { [weak self] in
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self?.showCustomAlert()
        }
    })
    
    // 2. UIHostingController로 SwiftUI 뷰 래핑
    let hostingController = UIHostingController(rootView: questDetailView)
    
    // 3. UIKit의 네비게이션 기능 설정
    hostingController.navigationItem.hidesBackButton = true
    setupCustomBackButton(for: hostingController)
    
    // 4. 네비게이션 컨트롤러를 통한 화면 전환
    navigationController?.pushViewController(hostingController, animated: true)
}

특징

  • UIKit 환경(HomeViewController)에서 SwiftUI 뷰(QuestDetailView)를 사용하기 위해 UIHostingController를 사용
  • UIHostingController가 SwiftUI 뷰를 UIKit의 뷰 계층구조에 통합하는 "호스트" 역할 수행
  • 네비게이션 컨트롤러 등 UIKit의 기능을 그대로 활용 가능
  • UIKit에서 SwiftUI 전체 뷰를 가져와야 할 때 사용.
  • SwiftUI 뷰는 독립적으로 렌더링되므로 UIKit의 UIView 계층 위에 SwiftUI 뷰를 덧씌우는 개념에 가깝다.

2. UIViewRepresentable: SwiftUI에서 UIKit 뷰를 사용하는 방법

  • 역할: SwiftUI 기반 프로젝트에서 UIKit의 UIView나 UIViewController를 SwiftUI 뷰로 "감싸는" 데 사용됩니다.
  • 사용 예시:
    • UIKit에서 제공하는 특정 기능(MapKit, AVPlayerViewController 등)을 SwiftUI에서 활용하고 싶을 때.
    • SwiftUI에서 아직 지원하지 않는 UIKit의 고유 뷰를 가져와야 할 때.

동작 방식

UIViewRepresentable 프로토콜을 채택한 구조체를 만들어 UIKit 뷰를 SwiftUI에서 사용할 수 있도록 래핑합니다.

// ImagePicker: UIKit의 UIImagePickerController를 SwiftUI에서 사용
struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    var sourceType: UIImagePickerController.SourceType
    var onImagePicked: (() -> Void)?
    
    // 1. UIKit 뷰컨트롤러 생성
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        return picker
    }
    
    // 2. 업데이트 로직
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
    
    // 3. Coordinator 생성
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
}

// QuestDetailView에서의 실제 사용
struct QuestDetailView: View {
    @State private var showImagePicker = false
    @State private var selectedImage: UIImage?
    
    var body: some View {
        // SwiftUI 뷰에서 UIKit 컴포넌트 사용
        ImagePicker(image: $selectedImage, sourceType: .camera) {
            // 이미지 선택 완료 시 동작
        }
    }
}
  • SwiftUI 환경에서 UIKit의 UIImagePickerController를 사용하기 위해 UIViewRepresentable 프로토콜 채택
  • makeUIViewController를 통해 실제 UIKit 컴포넌트 생성
  • Coordinator를 통해 UIKit의 델리게이트 패턴을 SwiftUI에서 처리

특징

  • SwiftUI에서 UIKit의 특정 뷰만 가져올 때 사용.
  • UIKit의 동작을 makeUIView와 updateUIView를 통해 SwiftUI 상태에 맞게 조정.

언제 UIHostingController vs UIViewRepresentable를 사용할까?

기능 UIHostingController UIViewRepresentable

사용 방향 UIKit → SwiftUI SwiftUI → UIKit
사용 목적 SwiftUI 전체 화면 또는 View를 UIKit에 통합 UIKit의 특정 뷰나 기능을 SwiftUI에 통합
유즈 케이스 UIKit 앱에 SwiftUI를 추가하거나 섞고 싶을 때 SwiftUI 앱에서 UIKit 뷰를 직접 써야 할 때

결론

  • UIHostingController는 UIKit에서 SwiftUI 전체를 사용
  • UIViewRepresentable은 SwiftUI에서 UIKit의 특정 기능만 가져온다.


솝커톤 예시코드

화면 전환만 있는 예시코드

반응형
저작자표시 비영리 변경금지 (새창열림)

'IOS - Swift > SwiftUI' 카테고리의 다른 글

[iOS/SwiftUI] SwiftUI에서 특정부분만 UIkit으로 추출해서 사용하기  (0) 2024.12.03
[iOS/SwiftUI] Property Wrapper - 기본편  (1) 2024.03.29
[iOS/SwiftUI] LunchScreen 적용하기  (0) 2023.12.31
'IOS - Swift/SwiftUI' 카테고리의 다른 글
  • [iOS/SwiftUI] SwiftUI에서 특정부분만 UIkit으로 추출해서 사용하기
  • [iOS/SwiftUI] Property Wrapper - 기본편
  • [iOS/SwiftUI] LunchScreen 적용하기
게게겍
게게겍
열심히 공부해보고 있습니다
  • 게게겍
    코더라도 되어보자
    게게겍
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • IOS - Swift
        • UIkit
        • SwiftUI
        • Combine
      • 혼자 공부한거
      • inflearn
      • 기타
      • 일기
      • firebase
      • CS
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    uikit
    private
    SwiftUI
    swift openapigenerator
    combine
    scan
    #GDSC #캐치카페 #대관 # 대학생 #취준생 #진학사
    replacemap
    subscription
    INTERNAL
    launchscreen
    UIHostingController
    flatMap
    ios
    compactMap
    UIViewRepresentable
    UICollectionView Custom Cell with Horizontal Scroll
    map
    open
    trymap
    viewBuilder
    fileprivate
    Swift
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
게게겍
[iOS] UIkit + SwiftUI 둘다 사용하기!
상단으로

티스토리툴바