Skip to content

Latest commit

 

History

History
245 lines (195 loc) · 5.07 KB

demo.md

File metadata and controls

245 lines (195 loc) · 5.07 KB

Present the project structure, build & run as empty.

Show that it's an iOS 11 project

Create PlaceholderView_Preview.swift

PlaceholderView_Preview

Creates a class that conforms to PreviewProvider protocol from Apple to allow previews

final class PlaceholderViewPreview: PreviewProvider {

  //previews here
}

You'll need to import SwiftUI for PreviewProvider to exists

import SwiftUI

And then some preview content to conform to the protocol, let's put some Text for now.

static var previews: some View {
    Text("Hello")
  }

Obviously we have some iOS 13 only code here so let's escape this

@available(iOS 13, *)

Show the canvas and then add those extras for retro-compatibility

#if canImport(SwiftUI) && DEBUG
#endif

If you want to bypass the device preview and see only your view you can add this

.previewLayout(.sizeThatFits)

With some padding to see it in better conditions

.padding(10)

If you want to see your view in several conditions then use a Group

Group {
      Text("Hello")
      Text("Hello").bold()
      Text("Hello").font(.largeTitle).bold()
    }.previewLayout(.sizeThatFits).padding(10)

But enough playing, I promise to help you using this tool to work on your views.

Let's create some helpers

UIViewPreview
import UIKit

#if canImport(SwiftUI) && DEBUG
import SwiftUI

struct UIViewPreview<View: UIView>: UIViewRepresentable {

  let view: View

  init(_ builder: @escaping () -> View) {
    view = builder()
  }

  // MARK: - UIViewRepresentable

  func makeUIView(context: Context) -> UIView {
    return view
  }

  func updateUIView(_ view: UIView, context: Context) {
    view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    view.setContentHuggingPriority(.defaultHigh, for: .vertical)
  }
}
#endif

We can now go back to our demo and replace the text by the actual placeholder view

UIViewPreview {
        PlaceholderView.loadFromNib()
      }

Having such a playground could lead you to add some convenience methods

extension PlaceholderView {

  static func placeholder(from state: State) -> PlaceholderView {
    let placeholder = PlaceholderView.loadFromNib()
    placeholder.state = state
    return placeholder
  }

}

For being able to do that

PlaceholderView.placeholder(from:
          PlaceholderView.State(
            emotion: "🎉",
            title: "It's working!",
            details: "Can you believe it?"
          )
        )

You can then add modifiers to test environements like dark mode

UIViewPreview {
        PlaceholderView.placeholder(from:
          PlaceholderView.State(
            emotion: "👻",
            title: "And in dark mode",
            details: "Its out of the box right?"
          )
        )
      }.environment(\.colorScheme, .dark)

You may need to rework your design a litte

override func awakeFromNib() {
    super.awakeFromNib()
    if #available(iOS 13.0, *) {
      backgroundColor = UIColor.systemBackground
    } else {
      backgroundColor = UIColor.white
    }
  }

Testing dynamic types

UIViewPreview {
        PlaceholderView.placeholder(from:
          PlaceholderView.State(
            emotion: "💟",
            title: "Testing dynamic types",
            details: "All users inclusive!"
          )
        )
      }.environment(\.sizeCategory, .accessibilityExtraExtraExtraLarge)

You can even add a display name to organize your renderings

.previewDisplayName("Accessibility ExtraExtraExtraLarge")

To exclude your preview files from release builds just add this build setting

EXCLUDED_SOURCE_FILE_NAMES = "*_Preview*"

One last demo by creating UIViewControllerPreview.swift file

UIViewControllerPreview
import UIKit

#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

Then create a Listing_Preview.swift file

Listing_Preview
import Foundation

#if canImport(SwiftUI) && DEBUG

import SwiftUI

@available(iOS 13, *)
final class ListingPreview: PreviewProvider {

  static var previews: some View {
    Group {
      UIViewControllerPreview { ListingViewController() }
    }
  }
}

#endif

You can then preview your view controllers in several devices and environments all at once

UIViewControllerPreview {
        ListingViewController()
      }.environment(\.sizeCategory, .extraExtraExtraLarge)
        .previewDevice("iPhone SE")
      UIViewControllerPreview {
        ListingViewController()
      }.environment(\.sizeCategory, .accessibilityExtraExtraExtraLarge)
      .previewDevice("iPad Pro (11-inch)")