Skip to content

Instantly share code, notes, and snippets.

@cfflymolo
Created March 19, 2018 05:23
Show Gist options
  • Save cfflymolo/0ad177ededa1e11346f806bd39ff0df9 to your computer and use it in GitHub Desktop.
Save cfflymolo/0ad177ededa1e11346f806bd39ff0df9 to your computer and use it in GitHub Desktop.
A modified version of Kickstarter's playground wrapper which is meant to simulate devices sizes in Xcode playgrounds. It will help with the design of UI elements in view controllers.
import UIKit
enum Device {
case iPhoneSE
case iPhone8
case iPhone8Plus
case iPhoneX
case iPad
}
enum Orientation {
case landscape
case portrait
}
/**
Creates a controller that represents a specific device, orientation with specific traits.
- parameter child: An optional controller to put inside the parent controller. If omitted
a blank controller will be used.
- parameter device: The device the controller should represent.
- parameter orientation: The orientation of the device.
- parameter contentSizeCategory: The content size category view controller should represent.
- parameter additionalTraits: An optional set of traits that will also be applied. Traits in this collection
will trump any traits derived from the device/orientation comboe specified.
- returns: A root controller that can be set to the playground's live view with the content
controller which should have UI elements added to it.
*/
func playgroundWrapper(child: UIViewController, device: Device = .iPhoneSE, orientation: Orientation = .portrait, contentSizeCategory: UIContentSizeCategory = .large, additionalTraits: UITraitCollection = .init()) -> UIViewController {
let parent: UIViewController = UIViewController()
parent.addChildViewController(child)
let traits: UITraitCollection
let parentSize: CGSize
switch (device, orientation) {
case (.iPhoneSE, .portrait):
parentSize = .init(width: 320, height: 568)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .phone)
])
case (.iPhoneSE, .landscape):
parentSize = .init(width: 568, height: 320)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .compact),
.init(userInterfaceIdiom: .phone)
])
case (.iPhone8, .portrait):
parentSize = .init(width: 375, height: 667)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .phone)
])
case (.iPhone8, .landscape):
parentSize = .init(width: 667, height: 375)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .compact),
.init(userInterfaceIdiom: .phone)
])
case (.iPhone8Plus, .portrait):
parentSize = .init(width: 414, height: 736)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .phone)
])
case (.iPhone8Plus, .landscape):
parentSize = .init(width: 736, height: 414)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .compact),
.init(userInterfaceIdiom: .phone)
])
case (.iPhoneX, .portrait):
parentSize = .init(width: 375, height: 812)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .compact),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .phone)
])
case (.iPhoneX, .landscape):
parentSize = .init(width: 812, height: 375)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .compact),
.init(userInterfaceIdiom: .phone)
])
case (.iPad, .portrait):
parentSize = .init(width: 768, height: 1024)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .pad)
])
case (.iPad, .landscape):
parentSize = .init(width: 1024, height: 768)
traits = .init(traitsFrom: [
.init(horizontalSizeClass: .regular),
.init(verticalSizeClass: .regular),
.init(userInterfaceIdiom: .pad)
])
}
let allTraits = UITraitCollection(traitsFrom: [
traits,
additionalTraits,
.init(preferredContentSizeCategory: contentSizeCategory)
])
parent.setOverrideTraitCollection(allTraits, forChildViewController: child)
parent.view.addSubview(child.view)
child.view.translatesAutoresizingMaskIntoConstraints = false
parent.view.frame.size = parentSize
parent.preferredContentSize = parentSize
parent.view.backgroundColor = .white
child.view.backgroundColor = .white
parent.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
child.view.leadingAnchor.constraint(equalTo: parent.view.leadingAnchor),
child.view.trailingAnchor.constraint(equalTo: parent.view.trailingAnchor),
child.view.topAnchor.constraint(equalTo: parent.view.topAnchor),
child.view.bottomAnchor.constraint(equalTo: child.view.bottomAnchor)
])
return parent
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment