Merge branch 'dev'
This commit is contained in:
commit
21404ec578
|
@ -3,3 +3,4 @@
|
|||
/Packages
|
||||
/*.xcodeproj
|
||||
xcuserdata/
|
||||
.swiftpm/xcode
|
||||
|
|
|
@ -5,6 +5,9 @@ import PackageDescription
|
|||
|
||||
let package = Package(
|
||||
name: "UIPreview",
|
||||
platforms: [
|
||||
.iOS(.v13)
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries a package produces, and make them visible to other packages.
|
||||
.library(
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension Binding {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
struct CatalogPage<Content: UIViewCatalogPresentable>: View {
|
||||
|
||||
let schemes: [ColorScheme]
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
ScrollView(.vertical, showsIndicators: true) {
|
||||
ForEach(values: Content.previewModels) { model in
|
||||
ForEach(values: schemes) { scheme in
|
||||
item(title: "\(scheme): \(model)") {
|
||||
ColorSchemePreview(scheme: scheme) {
|
||||
Content.preview(with: model)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.navigationBarTitle(String(describing: Content.self))
|
||||
}
|
||||
}
|
||||
|
||||
func item<Content: View>(title: String,
|
||||
@ViewBuilder content: @escaping () -> Content
|
||||
) -> some View {
|
||||
VStack(alignment: .center, spacing: 12.0) {
|
||||
Text(title)
|
||||
.font(.subheadline)
|
||||
.fontWeight(.bold)
|
||||
content()
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .center)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
struct CatalogPage_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CatalogPage<UISwitch>(schemes: [.light, .dark, ])
|
||||
CatalogPage<UILabel>(schemes: [.light, .dark, ])
|
||||
}
|
||||
}
|
|
@ -1,34 +1,30 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
struct ContentView: View {
|
||||
var body: some View {
|
||||
Text("Hello, world!")
|
||||
.background(Color(.red)).padding()
|
||||
extension UISwitch: UICatalogPresentable {
|
||||
public static var previewModels = [true, false]
|
||||
|
||||
public func apply(previewModel: Bool) {
|
||||
isOn = previewModel
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
.previewDarkTheme()
|
||||
extension UILabel: UICatalogPresentable {
|
||||
public static var previewModels: [String] {
|
||||
["123", "345", "Hello world", "How do you do"]
|
||||
}
|
||||
|
||||
public func apply(previewModel: String) {
|
||||
text = previewModel
|
||||
}
|
||||
|
||||
public static func makePreviewInstance() -> Self {
|
||||
let label = UILabel()
|
||||
label.adjustsFontForContentSizeCategory = true
|
||||
label.font = UIFont.preferredFont(forTextStyle: .caption1)
|
||||
return label as! Self
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
struct Demo_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group {
|
||||
UIViewPreview(UIView())
|
||||
.frame(width: 100, height: 30)
|
||||
.background(Color(.red))
|
||||
.previewLayout(.sizeThatFits)
|
||||
UIViewPreview(UILabel(), update: {
|
||||
$0.text = "Hello"
|
||||
$0.font = UIFont.preferredFont(forTextStyle: .caption1)
|
||||
$0.adjustsFontForContentSizeCategory = true
|
||||
}).previewAsComponent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension ForEach where Data.Element: Hashable, ID == Data.Element, Content: View {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension View {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension View {
|
||||
|
@ -24,7 +26,7 @@ struct ComponentPreview<Component: View>: View {
|
|||
ForEach(values: ColorScheme.allCases) { scheme in
|
||||
ForEach(values: ContentSizeCategory.smallestAndLargest) { category in
|
||||
self.component
|
||||
.previewLayout(.sizeThatFits)
|
||||
.previewLayout(.sizeThatFits).padding()
|
||||
.background(Color(.systemBackground))
|
||||
.colorScheme(scheme)
|
||||
.environment(\.sizeCategory, category)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
|
||||
//xcrun simctl list devicetypes
|
||||
public let defaultDeviceNames: [String] =
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
public enum UICatalog {
|
||||
public enum Theme {
|
||||
case light, dark
|
||||
}
|
||||
|
||||
public static func makePreviewPage<Content>(_ content: Content.Type,
|
||||
themes: [Theme] = [.light, .dark]
|
||||
) -> UIViewController where Content: UIViewCatalogPresentable {
|
||||
guard #available(iOS 13, *) else {
|
||||
return UIViewController()
|
||||
}
|
||||
return CatalogPage<Content>(schemes: themes.map(\.scheme)).asViewController()
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension UICatalog.Theme {
|
||||
var scheme: ColorScheme {
|
||||
switch self {
|
||||
case .light: return .light
|
||||
case .dark: return .dark
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
public protocol UICatalogPresentable {
|
||||
associatedtype PreviewModel: Hashable
|
||||
|
||||
func apply(previewModel: PreviewModel)
|
||||
|
||||
static var previewModels: [PreviewModel] { get }
|
||||
|
||||
static func makePreviewInstance() -> Self
|
||||
}
|
||||
|
||||
public typealias UIViewCatalogPresentable = UIView & UICatalogPresentable
|
||||
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension UICatalogPresentable where Self: UIView {
|
||||
public func preview(with model: PreviewModel) -> some View {
|
||||
UIViewPreview(self) { $0.apply(previewModel: model) }
|
||||
}
|
||||
|
||||
public static func preview(with model: PreviewModel) -> some View {
|
||||
makePreviewInstance().preview(with: model)
|
||||
}
|
||||
|
||||
public static func makePreviewInstance() -> Self { self.init() }
|
||||
}
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
public struct UIViewControllerPreview<ContentView: UIViewController>: UIViewControllerRepresentable {
|
||||
let contextBuilder: () -> ViewCoordinator<ContentView>
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
public struct UIViewPreview<ContentView: UIView>: UIViewRepresentable {
|
||||
let contextBuilder: () -> ViewCoordinator<ContentView>
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#if canImport(SwiftUI)
|
||||
import SwiftUI
|
||||
#endif
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
extension View {
|
||||
public func asViewController() -> UIViewController {
|
||||
UIHostingController(rootView: self)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue