|
1 | 1 | # PreviewView
|
2 | 2 |
|
3 |
| -Make use of SwiftUI previews for rapidly protyping your UIViewControllers and UIViews! |
| 3 | +Make use of SwiftUI previews for rapidly protyping your `UIViewControllers` and `UIViews`! |
4 | 4 |
|
5 |
| -### Previewing a `UIView` |
| 5 | +## Important Note |
| 6 | + |
| 7 | +The SwiftUI preview canvas is tied to a specific version of Xcode, not the the target OS version. This means you can make use of this utility even if you're not targetting iOS 13 or higher, as long as you're using Xcode 10 or higher. |
| 8 | + |
| 9 | +If your application targets earlier than iOS 13 you will need to do is mark your `PreviewProvider` structs with an `@available(iOS 13, *)` attribute to ensure the app can still compile. |
| 10 | + |
| 11 | +## Installation |
| 12 | + |
| 13 | +You can manually drop the files into your project, or take a look at Apple's documentation for [adding Swift Packages in Xcode](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app). |
| 14 | + |
| 15 | +Adding this as a dependency on a Swift Package is **not** recommended as it will then force the dependency on anyone that consumes your library. |
| 16 | + |
| 17 | +## Previewing a view |
6 | 18 |
|
7 | 19 | ```swift
|
8 | 20 | struct YourViewController_Previews: PreviewProvider {
|
9 | 21 | static var previews: some View {
|
10 |
| - Preview(for: YourView()) |
| 22 | + ViewPreview(YourView()) |
11 | 23 | .previewLayout(.fixed(width: 375, height: 86))
|
12 | 24 | }
|
13 | 25 | }
|
14 | 26 | ```
|
15 | 27 |
|
16 |
| -Update the `previewLayout` values to be the typical size of your view. |
| 28 | +**Important:** Update the `previewLayout` values to be the typical size of your view. |
| 29 | + |
| 30 | +## Previewing a view controller |
17 | 31 |
|
18 |
| -### Previewing a `UIViewController` |
| 32 | +### Standalone |
19 | 33 |
|
20 | 34 | ```swift
|
21 | 35 | struct YourViewController_Previews: PreviewProvider {
|
22 | 36 | static var previews: some View {
|
23 |
| - Preview(for: YourViewController()) |
| 37 | + ViewControllerPreview(YourViewController()) |
| 38 | + .edgesIgnoringSafeArea(.all) |
24 | 39 | }
|
25 | 40 | }
|
26 | 41 | ```
|
27 | 42 |
|
28 |
| -### Previewing a `UIViewController` embedded in a `UINavigationController` |
29 |
| - |
30 |
| -#### With a standard navigation bar |
| 43 | +If you wish to test a custom `UINavigationController` you can do so with `ViewControllerPreview`. |
31 | 44 |
|
32 | 45 | ```swift
|
33 |
| -struct YourViewController_Previews: PreviewProvider { |
| 46 | +struct YourNavigationController_Previews: PreviewProvider { |
34 | 47 | static var previews: some View {
|
35 |
| - Preview(navigationControllerFor: YourViewController()) |
| 48 | + ViewControllerPreview(YourNavigationController()) |
| 49 | + .edgesIgnoringSafeArea(.all) |
36 | 50 | }
|
37 | 51 | }
|
38 | 52 | ```
|
39 | 53 |
|
40 |
| -#### With a large title navigation bar |
| 54 | +### Embedded in a `UINavigationController` |
41 | 55 |
|
42 | 56 | ```swift
|
43 | 57 | struct YourViewController_Previews: PreviewProvider {
|
44 | 58 | static var previews: some View {
|
45 |
| - Preview(navigationControllerFor: YourViewController(), withNavigationBarStyle: .largeTitle) |
| 59 | + NavigationControllerPreview { |
| 60 | + YourViewController() |
| 61 | + } |
| 62 | + .edgesIgnoringSafeArea(.all) |
46 | 63 | }
|
47 | 64 | }
|
48 | 65 | ```
|
49 | 66 |
|
50 |
| -#### Without a navigation bar |
51 |
| - |
52 |
| -Helpful when you may be using Live Preview and any other view controllers that are pushed from your view controller require a navigation bar. |
| 67 | +The body content of the `NavigationControllerPreview` accepts an entire navigation stack, allowing your previews to show back bar button items, and even be navigatable in Live Preview. |
53 | 68 |
|
54 | 69 | ```swift
|
55 |
| -struct YourViewController_Previews: PreviewProvider { |
| 70 | +struct DetailViewController_Previews: PreviewProvider { |
56 | 71 | static var previews: some View {
|
57 |
| - Preview(navigationControllerFor: YourViewController(), withNavigationBarStyle: .none) |
| 72 | + NavigationControllerPreview { |
| 73 | + ListViewController() |
| 74 | + DetailViewController() |
| 75 | + } |
| 76 | + .edgesIgnoringSafeArea(.all) |
58 | 77 | }
|
59 | 78 | }
|
60 | 79 | ```
|
61 | 80 |
|
62 |
| -### Previewing a `UIViewController` embedded in a `UITabBarController` |
| 81 | +You can customise the navigation bar settings and toolbar settings of the navigation controller via the initializer parameters. |
63 | 82 |
|
64 | 83 | ```swift
|
65 |
| -struct YourViewController_Previews: PreviewProvider { |
| 84 | +struct DetailViewController_Previews: PreviewProvider { |
66 | 85 | static var previews: some View {
|
67 |
| - Preview(tabBarControllerFor: YourViewController()) |
| 86 | + NavigationControllerPreview(barStyle: .largeTitle, showsToolbar: true) { |
| 87 | + ListViewController() |
| 88 | + DetailViewController() |
| 89 | + } |
| 90 | + .edgesIgnoringSafeArea(.all) |
68 | 91 | }
|
69 | 92 | }
|
70 | 93 | ```
|
71 | 94 |
|
72 |
| -You can also have the preview show the tab bar with other tab items <sup>1</sup>. By default your supplied view controller will be shown in the first position of the tab bar. |
| 95 | +### Embedded in a `UITabBarController` |
73 | 96 |
|
74 | 97 | ```swift
|
75 | 98 | struct YourViewController_Previews: PreviewProvider {
|
76 |
| - static let secondTabBarItem = UITabBarItem(title: "First", |
77 |
| - image: UIImage(systemName: "capsule"), |
78 |
| - selectedImage: UIImage(systemName: "capsule.fill")) |
79 |
| - |
80 |
| - static let thirdTabBarItem = UITabBarItem(title: "Third", |
81 |
| - image: UIImage(systemName: "diamond"), |
82 |
| - selectedImage: UIImage(systemName: "diamond.fill")) |
83 |
| - |
84 | 99 | static var previews: some View {
|
85 |
| - Preview(tabBarControllerFor: YourViewController(), withOtherTabs: secondTabBarItem, thirdTabBarItem) |
| 100 | + TabBarControllerPreview { |
| 101 | + ViewControllerPreview(YourViewController()) |
| 102 | + } |
| 103 | + .edgesIgnoringSafeArea(.all) |
86 | 104 | }
|
87 | 105 | }
|
88 | 106 | ```
|
89 | 107 |
|
90 |
| -You can have it shown at any other position by providing a position index parameter. The following code the view controller will be shown in the second position. |
| 108 | +Displaying a single tab would be weird, so to allow your previews to closely match your real app you can provide the other tabs within the body. |
91 | 109 |
|
92 | 110 | ```swift
|
93 | 111 | struct YourViewController_Previews: PreviewProvider {
|
94 |
| - static let firstTabBarItem = UITabBarItem(title: "First", |
95 |
| - image: UIImage(systemName: "capsule"), |
96 |
| - selectedImage: UIImage(systemName: "capsule.fill")) |
| 112 | + static var previews: some View { |
| 113 | + TabBarControllerPreview { |
| 114 | + PreviewBlankTabItem(title: "First", symbolNamed: "capsule") |
| 115 | + |
| 116 | + ViewControllerPreview(YourViewController()) |
| 117 | + |
| 118 | + ViewControllerPreview(YourOtherViewController()) |
| 119 | + } |
| 120 | + .edgesIgnoringSafeArea(.all) |
| 121 | + } |
| 122 | +} |
| 123 | +``` |
97 | 124 |
|
98 |
| - static let thirdTabBarItem = UITabBarItem(title: "Third", |
99 |
| - image: UIImage(systemName: "diamond"), |
100 |
| - selectedImage: UIImage(systemName: "diamond.fill")) |
| 125 | +You can even embed your view controllers in a navigation controller to get the full in-app experience. |
101 | 126 |
|
| 127 | +```swift |
| 128 | +struct YourViewController_Previews: PreviewProvider { |
102 | 129 | static var previews: some View {
|
103 |
| - Preview(tabBarControllerFor: YourViewController(), atPosition: 1, withOtherTabs: firstTabBarItem, thirdTabBarItem) |
| 130 | + TabBarControllerPreview { |
| 131 | + PreviewBlankTabItem(title: "First", symbolNamed: "capsule") |
| 132 | + |
| 133 | + NavigationControllerPreview { |
| 134 | + YourViewController() |
| 135 | + } |
| 136 | + |
| 137 | + PreviewBlankTabItem(title: "Third", symbolNamed: "diamond") |
| 138 | + } |
| 139 | + .edgesIgnoringSafeArea(.all) |
104 | 140 | }
|
105 | 141 | }
|
106 | 142 | ```
|
107 | 143 |
|
108 |
| -### Pro Tip |
| 144 | +## Pro Tip |
109 | 145 |
|
110 | 146 | Did you know that you can easily create multiple previews with a simple `ForEach` loop?
|
111 | 147 |
|
112 | 148 | ```swift
|
113 | 149 | struct YourViewController_Previews: PreviewProvider {
|
| 150 | + static let supportedDevices = ["iPhone 11", "iPhone 8", "iPhone SE (1st generation)"] |
| 151 | + |
114 | 152 | static var previews: some View {
|
115 |
| - ForEach(["iPhone 11", "iPhone 8", "iPhone SE (1st generation)"], id: \.self) { deviceName in |
116 |
| - Preview(for: YourViewController()) |
| 153 | + ForEach(Self.supportedDevices, id: \.self) { deviceName in |
| 154 | + ViewControllerPreview(YourViewController()) |
117 | 155 | .previewDevice(PreviewDevice(rawValue: deviceName))
|
118 | 156 | .previewDisplayName(deviceName)
|
119 | 157 | }
|
|
0 commit comments