Skip to content

Instantly share code, notes, and snippets.

@SergLam
Created January 7, 2021 20:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SergLam/1dff24efdc2fe3827ad7ff92755a6bc2 to your computer and use it in GitHub Desktop.
Save SergLam/1dff24efdc2fe3827ad7ff92755a6bc2 to your computer and use it in GitHub Desktop.
SwiftUI previews for UIKit
import UIKit
final class CustomVC: UIViewController {
private lazy var contentView: CustomView = CustomView()
// MARK: - Life cycle
deinit {
NotificationCenter.default.removeObserver(self)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .default
}
override func loadView() {
view = contentView
}
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
// MARK: - Private functions
private func setup() {
}
}
#if DEBUG
#if targetEnvironment(simulator)
import SwiftUI
@available(iOS 13.0, *)
struct CustomVC_Previews: PreviewProvider {
static var devices = AppConstants.previewDevices // ["iPhone SE (1st generation)", "iPhone 8 (14.3)", "iPhone 12", "iPhone 12 Pro Max"]
static var platform: PreviewPlatform? {
return SwiftUI.PreviewPlatform.iOS
}
static var previews: some SwiftUI.View {
ForEach(devices, id: \.self) { deviceName in
Group {
UIViewControllerPreview {
MainVC()
}
}.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
}
}
}
#endif
#endif
final class CustomView: UIView {
// MARK: - Life cycle
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
// MARK: - Private functions
private func setup() {
setupLayout()
}
private func setupLayout() {
layer.cornerRadius = 8.0
clipsToBounds = true
layer.borderWidth = 1.0
layer.borderColor = UIColor.black.cgColor
}
}
#if DEBUG
#if targetEnvironment(simulator)
import SwiftUI
@available(iOS 13.0, *)
struct CustomViewn_Previews: PreviewProvider {
static var devices = AppConstants.previewDevices // ["iPhone SE (1st generation)", "iPhone 8 (14.3)", "iPhone 12", "iPhone 12 Pro Max"]
static var platform: PreviewPlatform? {
return SwiftUI.PreviewPlatform.iOS
}
static var previews: some SwiftUI.View {
ForEach(devices, id: \.self) { deviceName in
Group {
UIViewPreview {
CustomView(frame: CGRect.zero)
}.frame(minWidth: 100, maxWidth: 200, minHeight: 50, maxHeight: 50)
}.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
}
}
}
#endif
#endif
// Inspired by CocoaHeads Ukraine 2020 Session - https://www.youtube.com/watch?v=V03NMBjumjA
// Aware of static libs at Cocoapods - installer fix below
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
config.build_settings['MATCH_O_TYPE'] = 'staticlib'
config.build_settings['MATCH_O_TYPE[sdk=iphonesimulator*]'] = 'mh_dylib'
if config.name == 'Debug'
config.build_settings['OTHER_SWIFT_FLAGS'] = ['$(inherited)', '-Onone']
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Owholemodule'
end
end
end
installer.generated_projects.each do |project|
project.build_configurations.each do |bc|
bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
end
end
end
import SwiftUI
import UIKit
@available(iOS 13.0, *)
struct UIViewControllerPreview: SwiftUI.View {
private let factory: () -> UIViewController
init(factory: @escaping () -> UIViewController) {
self.factory = factory
}
var body: some SwiftUI.View {
Renderer(factory)
}
private struct Renderer: UIViewControllerRepresentable {
private let factory: () -> UIViewController
init(_ factory: @escaping () -> UIViewController) {
self.factory = factory
}
func makeUIViewController(context: Context) -> UIViewController {
return factory()
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
}
}
import SwiftUI
import UIKit
@available(iOS 13.0, *)
struct UIViewPreview: SwiftUI.View {
private let factory: () -> UIView
init(factory: @escaping () -> UIView) {
self.factory = factory
}
var body: some SwiftUI.View {
Renderer(factory)
}
private struct Renderer: UIViewRepresentable {
private let factory: () -> UIView
init(_ factory: @escaping () -> UIView) {
self.factory = factory
}
func makeUIView(context: Context) -> UIView {
return factory()
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment