본문 바로가기
UIKit

UIKit에서 SwiftUI처럼 Preview를 사용하는 방법

by 리버🐦‍🔥 2023. 10. 2.

아래 코드를 Preview를 보고싶은 ViewController에 붙여넣으면 SwiftUI처럼 Preview를 사용할 수 있다.

// UIKit으로 짠 화면을 SwiftUI로 바로 볼 수 있게 해주는 코드
import SwiftUI

#if DEBUG
extension UIViewController {
    private struct Preview: UIViewControllerRepresentable {
            let viewController: UIViewController

            func makeUIViewController(context: Context) -> UIViewController {
                return viewController
            }

            func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
            }
        }

        func toPreview() -> some View {
            Preview(viewController: self)
        }
}
#endif

import SwiftUI
@available(iOS 13.0.0, *)
struct ViewControllerPreView: PreviewProvider {
    static var previews: some View {
        ViewController().toPreview()
    }
}

위 코드를 뷰 컨트롤러를 만들 때마다 매번 반복하여 적지 않기 위해서는 Extension+ViewControllerPreView을 만들어 Extension부분을 따로 빼고, Preview부분만 각 컨트롤러에 넣어주는 것도 가능하다.

 

1. Extension+UIViewController.swift에 Extension을 따로 분리해서 작성한다.

// Extension+UIViewController.swift
// UIKit으로 짠 화면을 SwiftUI로 바로 볼 수 있게 해주는 코드
import SwiftUI

#if DEBUG
extension UIViewController {
    private struct Preview: UIViewControllerRepresentable {
            let viewController: UIViewController

            func makeUIViewController(context: Context) -> UIViewController {
                return viewController
            }

            func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
            }
        }

        func toPreview() -> some View {
            Preview(viewController: self)
        }
}
#endif

2. 각 컨트롤러별로 동일하게 Preview에 관련된 코드를 작성한다. 이 때, 위에서 선언한 Extension부분은 빼도 된다.

//
//  UIViewTest.swift
//  UIKit-Study
//
//  Created by Kyungsoo Lee on 2023/09/30.
//

import UIKit

class UIViewTest: UIViewController {
    // MARK: - UIView
    private lazy var uiView: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        view.translatesAutoresizingMaskIntoConstraints = false
        
        return view
    }()

    // MARK: - viewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = .systemGray
        
        // 뷰 추가(아직 layout 설정 안된 상태)
        self.view.addSubview(uiView)
        
        setLayout()
    }

    // MARK: - UIView 제약조건
    private func setUIViewLayout() {
        let uiViewConstraint = [
            uiView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            uiView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            uiView.widthAnchor.constraint(equalToConstant: 100),
            uiView.heightAnchor.constraint(equalToConstant: 100)
        ]
        // 제약 조건을 활성화 시켜 오토 레이아웃 설정한다.
        NSLayoutConstraint.activate(uiViewConstraint)
    }

    // MARK: - 전체 제약조건 설정
        // 컴포넌트들의 레이아웃을 설정한다
        private func setLayout() {
            // 프레임 기반의 레이아웃을 비활성화 하여 오토 레이아웃을 기반으로 설정할 수 있도록 한다.
            
            // UIView 제약조건 설정
            setUIViewLayout()
        }
}

// 이 부분이 Preview부분이 된다. Extension을 따로 두어 컨트롤러마다 선언해 줄 필요가 없어졌다.
import SwiftUI

@available(iOS 13.0.0, *)
struct UIViewTestPrebiew: PreviewProvider {
    static var previews: some View {
        UIViewTest().toPreview()
    }
}