Created
March 19, 2018 05:23
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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