Merge branch 'dev'

This commit is contained in:
Alexandr Goncharov 2020-10-15 17:46:10 +03:00
commit 21404ec578
14 changed files with 162 additions and 27 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
/Packages
/*.xcodeproj
xcuserdata/
.swiftpm/xcode

View File

@ -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(

View File

@ -1,4 +1,7 @@
#if canImport(SwiftUI)
import SwiftUI
#endif
import UIKit
@available(iOS 13, *)
extension Binding {

View File

@ -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, ])
}
}

View File

@ -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()
}
}
}

View File

@ -1,4 +1,6 @@
#if canImport(SwiftUI)
import SwiftUI
#endif
@available(iOS 13, *)
extension ForEach where Data.Element: Hashable, ID == Data.Element, Content: View {

View File

@ -1,4 +1,6 @@
#if canImport(SwiftUI)
import SwiftUI
#endif
@available(iOS 13, *)
extension View {

View File

@ -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)

View File

@ -1,4 +1,6 @@
#if canImport(SwiftUI)
import SwiftUI
#endif
//xcrun simctl list devicetypes
public let defaultDeviceNames: [String] =

View File

@ -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
}
}
}

View File

@ -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() }
}

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,11 @@
#if canImport(SwiftUI)
import SwiftUI
#endif
import UIKit
@available(iOS 13, *)
extension View {
public func asViewController() -> UIViewController {
UIHostingController(rootView: self)
}
}