-
[UIKit] UIKit의 스토리보드 Preview 적용하기(Storyboard, Preview, 미리보기)/iOS 📱 2024. 12. 8. 14:35반응형
안녕하세요 아렉스입니다 :>
WWDC 23 이후로 프리뷰를 하는 방식은 2가지가 되었습니다.
UIKit 환경에서도 Preview를 이용하니 매우 편한 개발 경험이 생겼습니다. 코드베이스로 된 경우에는 잘 사용하셨는데, 스토리보드로 된 뷰컨에서는 활용 못하는 분들이 있어서 글을 작성해봅니다.
스토리보드로 된 뷰컨을 Preview 하기 전 현재 사용되는 방법들에 대해서 간략히 설명하겠습니다.
Preview 방식 - 1
매크로가 소개 되기 전 사용했던 방식입니다.
UIViewControllerRepresentable 를 SwiftUI 뷰로 통합하기 위해 사용되는 프로토콜입니다.
결과적으로만 보면 간단해보이지만, 처음 이 코드를 접했을 때, Preview에 활용하는 아이디어에 놀랐던 기억이 있네요import SwiftUI extension UIViewController { struct Preview: UIViewControllerRepresentable { let viewController: UIViewController func makeUIViewController(context: Context) -> UIViewController { viewController } func updateUIViewController(_ uiView: UIViewController,context: Context) {} } func toPreview() -> some View { Preview(viewController: self) } }
사용 방식은 아래와 같습니다.struct ViewController_PreviewProvider: PreviewProvider { static var previews: some View { ViewController() .toPreview() } }
Preview 방식 - 2
WWDC 23에 발표 된 매크로를 이용한 프리뷰입니다.
직접적으로 SwiftUI 프레임워크를 import 하지도, extension을 별도 구현하지않아도 되는 점이 매우 편리합니다.#Preview { ViewController() }
위에 코드들을 스토리보드에 적용시
현재 스토리보드에는 Alert를 표시해주는 Button이 하나 있습니다.
왼쪽 사진은 스토리보드, 우측 사진은 Preview 입니다.
위 두개의 방식을 예제를 통해 적용해봐도 안되는 것을 볼 수 있습니다 !-> 아 ! 스토리보드 이래서 안 쓰는구나 !
Why ?
방식 1 코드
extension UIViewController { struct Preview: UIViewControllerRepresentable { let viewController: UIViewController // 이 메서드에서 반환 된 인스턴스를 Preview 해줌 func makeUIViewController(context: Context) -> UIViewController { viewController } } }
방식 2에서 사용 된 매크로 구문
@available(iOS 17.0, macOS 14.0, tvOS 17.0, *) @freestanding(declaration) public macro Preview( _ name: String? = nil, traits: PreviewTrait<Preview.ViewTraits>..., @PreviewMacroBodyBuilder<UIViewController> body: @escaping @MainActor () -> UIViewController ) = #externalMacro(module: "PreviewsMacros", type: "KitViewMacro")
방식 1,2 를 살펴보니 Preview를 해주는 것은 반환 된 UIViewController를 사용합니다.
위 코드에서 반환 해준 것이 스토리보드를 통해 생성 된 인스턴스가 아니기 때문입니다.
How to ?
스토리보드의 뷰컨트롤러를 인스턴스화하여 화면 전환했던 경험이 있으신가요 ?
그 아이디어를 그대로 사용합니다. 마치 UIViewControllerRepresentable 를 Preview에 사용했던 아이디어처럼 말이죠struct ViewController_PreviewProvider: PreviewProvider { static var previews: some View { let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewController( withIdentifier: "ViewController" ) return vc.toPreview() } }
#Preview { let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewController( withIdentifier: "ViewController" ) return vc }
결과
UIButton과, UIButton에 대한 @IBAction 도 Preview에서 작동하는 것을 볼 수 있습니다.
etc
1. #Preview 쓰고싶은데 버전이 안 맞아서 에러가 나와서 사용 못하고 있어요.
-> @available 를 사용@available(iOS 17.0, *) #Preview {}
2. 매번 쓰는게 귀찮아요
스토리보드 identifier 지정시 클래스 이름과 동일하게 지정하는 관례를 통해 아래와 같은 인터페이스를 구현할 수 있습니다.protocol Previewable { associatedtype T static func createViewController( with storyboard: String ) -> T } // 기본 구현 extension Previewable { static func createViewController( with storyboard: String = "Main" ) -> T { let storyboard = UIStoryboard(name: storyboard, bundle: nil) let vc = storyboard.instantiateViewController( withIdentifier: String(describing: T.self) ) as! T return vc } }
사용 방법1. Previewable 채택하기 2. 스토리보드 identifier로 사용할 타입 지정 class ViewController: UIViewController, Previewable { typealias T = ViewController }
https://developer.apple.com/documentation/swiftui/uiviewcontrollerrepresentable' > iOS 📱' 카테고리의 다른 글
[iOS] Meet AccessorySetupKit 정리 (0) 2024.06.14 [iOS] Storyboard에서 accessibilityIdentifier 설정하기 (User Defined Runtime Attributes) (0) 2024.03.13 [iOS] HTTP 통신 허용 (0) 2023.11.04 [iOS] class가 NSObject를 상속받아야할 때 (NSObjectProtocol) (1) 2023.11.04 [iOS] 하이브리드 앱 개발시 Bridge 구현 (Javascript와 통신하기 - WKScriptMessageHandler) (0) 2023.11.03