SwiftUI previews can be used for UIViewController
and UIView
in UIKit. Simply add the following structs to your UIKit application and then create the associated view providers.
ViewController.swift
import UIKit
final class ViewController: UIViewController {
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .systemBlue
button.setTitle("Button", for: .normal)
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
#if canImport(SwiftUI) && DEBUG
import SwiftUI
struct UIViewControllerPreview<ViewController: UIViewController>: UIViewControllerRepresentable {
let viewController: ViewController
init(_ builder: @escaping () -> ViewController) {
viewController = builder()
}
// MARK: - UIViewControllerRepresentable
func makeUIViewController(context: Context) -> ViewController {
viewController
}
func updateUIViewController(_ uiViewController: ViewController, context: UIViewControllerRepresentableContext<UIViewControllerPreview<ViewController>>) {
return
}
}
#endif
#if canImport(SwiftUI) && DEBUG
import SwiftUI
let deviceNames: [String] = [
"iPhone SE",
"iPhone 11 Pro Max",
"iPad Pro (11-inch)"
]
@available(iOS 13.0, *)
struct ViewController_Preview: PreviewProvider {
static var previews: some View {
ForEach(deviceNames, id: \.self) { deviceName in
UIViewControllerPreview {
ViewController()
}.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
}
}
}
#endif
SimpleView.swift
import Foundation
import UIKit
final class SimpleView: UIView {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Simple Label"
addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: centerXAnchor),
label.centerYAnchor.constraint(equalTo: centerYAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
return CGSize(width: 200, height: 200)
}
}
#if canImport(SwiftUI) && DEBUG
import SwiftUI
@available(iOS 13, *)
public struct UIViewPreview<View: UIView>: UIViewRepresentable {
public let view: View
public init(_ builder: @escaping () -> View) {
view = builder()
}
// MARK: - UIViewRepresentable
public func makeUIView(context: Context) -> UIView {
return view
}
public func updateUIView(_ view: UIView, context: Context) {
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
view.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
}
#endif
#if canImport(SwiftUI) && DEBUG
import SwiftUI
@available(iOS 13.0, *)
struct SimpleView_Preview: PreviewProvider {
static var previews: some View {
UIViewPreview {
let button = SimpleView()
return button
}.previewLayout(.sizeThatFits)
.padding(10)
}
}
#endif