Layers are the fundamental building block of Prototope.

A layer displays content (a color, an image, etc.) and can route touch events.

Layers are stored in a tree. It’s possible to make a layer without a parent, but only layers in the tree starting at Layer.root will be displayed.

let redLayer = Layer(parent: Layer.root)
redLayer.backgroundColor =
redLayer.frame = Rect(x: 50, y: 50, width: 100, height: 100)

But first things first: how do you set Layer.root?

Getting started

in iOS Setting a root layer requires having a uiview available to you. Typically, you can use the view available to you from your main ViewController’s viewDidLoad method. When you have that, you can set it as your root using Layer.setRoot() like so:

override func viewDidLoad() {
    Layer.setRoot(fromView: view)

Once you have a root layer, you are free to create named layers, give layers sizes, add layers to those layers and begin adding behaviors to those layers. Prototope’s layers are similar to divs in html and Layer()s in Framer.

You can create a layer with just a background color or you can create one with an image. If you go the image route, the layer is sized to match the image.

Method reference

  • Creating and identifying layers

  • public class func setRoot(fromView view: UIView)

    Call this method, likely in your ViewController.swift file, probably like:

    override func viewDidLoad() {
        Layer.setRoot(fromView: view)

    this sets your root layer to be the main view of your ios app. As a result, making new Layers with Layer.root as their parent will result in them appearing on the screen (which is usually what you want)

  • public init(parent: Layer? = nil, name: String? = nil)

    Setting a name on a layer allows you to access it later on using methods like sublayerNamed, descendentNamed or ancestorNamed.

  • public convenience init(parent: Layer?, imageName: String)

    Setting an imageName will look for the image in your project with a matching name.

    in iOS, you do not need to specify the file extension, you may simply write

    sled: Layer = Layer(nil, "dogesled")

    This will match “dogesled.png”, “dogesled.jpg”, and even “dogesled@2x.png” on hidpi devices

  • public convenience init(wrappingCALayer: CALayer, name: String? = nil)

    If you, for some reason, have access to a raw CALayer then you’ve come to the right initializer.

  • Core Layer Variables

  • public class var root: Layer

  • public let name: String?

  • Layer hierarchy access and manipulation

  • Variables for layer hierarchy

  • public weak var parent: Layer?

  • public private(set) var sublayers: [Layer] = []

  • public var sublayerAtFront: Layer?

    Layers stack, in order in which they are added. A layer added last to some parent will appear to be the frontmost layer.

  • public var zPosition: Double

    Sets the zPosition of the layer. Higher values go towards the screen as the z axis increases towards your face. Measured in points and defaults to 0. Animatable, but not yet with dynamic animators.

  • public func ancestorNamed(name: String) -> Layer?

  • public func sublayerNamed(name: String) -> Layer?

  • public func descendentNamed(name: String) -> Layer?

  • public func descendentAtPath(pathElements: [String]) -> Layer?

  • public func removeAllSublayers()

  • Geometry

  • Variables

    All the geometry variables of Layers are read/write, such that setting any of these variables will cause the layer to update to that value.

  • var x: Double

    sets the x position of the middle of your layer, relative to its parent.

  • var y: Double

    sets the y position of the middle of your layer, relative to its parent.

  • var position: Point

    If you have received a point (possibly from a touch handler), you may use that value directly to set a layer’s x/y pair directly.

  • var width: Double

    Sets the width of the layer in device points.

  • var height: Double

    Sets the height of the layer in device points.

  • var size: Size

    Sets the width and height at once, if you have received a Size from some other method.

  • var frame: Rect

    Similar to size, the frame defines both the size and the position of the layer with respect to its parent. See the Rect docs for more information about Rects (which are defined by an origin and a size).

    Because the frame is defined with respect to the layer’s parent, it’s usually best to modify the frame when operating in the parent’s context.

  • var bounds: Rect

  • var anchorPoint: Point

  • var rotationDegrees: Double

  • var rotationRadians: Double = 0

  • var scale: Double

  • var scaleX: Double = 1

  • var scaleY: Double = 1

  • var globalPosition: Point

  • Using dynamic animators

    Dynamic animators are different from traditional animations in that they specify a final resting place for values and a spring damping and initial velocity to get there. As a result, while animations seem to ‘make sense visually’, their timing may be unpredictable.

  • public var animators: LayerAnimatorStore

    Provides access to a collection of dynamic animators for the properties on this layer.

    If you want a layer to animate towards a point in a physical fashion (i.e. with speed determined by physical parameters, not a fixed duration), or if you want to take into account gesture velocity, this is your API.

    For example, this dynamically animates someLayer’s x value to 400 using velocity from a touch sequence: = 400
    someLayer.animators.x.velocity = touchSequence.currentVelocityInLayer(someLayer.superlayer!)

    See documentation for LayerAnimatorStore and Animator for more information.

    If you just want to change a bunch of values in a fixed-time animation, see Layer.animateWithDuration(:, animations:, completionHandler:).

  • public func containsGlobalPoint(point: Point) -> Bool

    Is a point in Layer.root’s coordinate space enclosed by this Layer?

  • public func convertGlobalPointToLocalPoint(globalPoint: Point) -> Point

    Returns a point in the Layer’s coordinate space (i.e. if you have somehow captured a touch event in Layer.root but you want to know where in your layer that is)

  • public func convertLocalPointToGlobalPoint(localPoint: Point) -> Point

    Returns a point from your special layer in the coordinate space of Layer.root

  • Appearance

  • Variables

  • public var backgroundColor: Color?

    Sets the background color of the layer. Look at the docs for Color to see what you can feed this.

  • public var alpha: Double

    Sets the opacity of the layer and all its descendents. If you only want to change the opacity of the background color, that can be set in backgroundColor directly.

  • public var cornerRadius: Double

    Sets how rounded the corners are in device points.

    By default, setting a corner radius will crop the contents (images) of the layer so that the radius is visible.

  • public var image: Image?

    Sets an image to be the primary content of the layer.

  • public var border: Border

    Sets the border properties of the layer.

  • public var shadow: Shadow

    Sets the shadow of the layer.

    If a shadow and a corner radius are set, you cannot also have an image in your layer. This is because for corner radius to work, the layer needs to clip its contents, but in order for shadows to work, you can’t clip the content.

    A fix, however, if you want all three, is to round the image (png) outright and then apply a shadow, the Shadow property is set on the opaque portions of a layer’s image.

  • public var layerMask: Layerthis.layerMaskLayer

    The mask layer is used to clip or filter the contents of a layer. Those contents will be rendered only where the mask layer’s contents are opaque. Partially transparent regions of the mask layer will result in partially transparent renderings of the host layer.

    The mask layer operates within the coordinate space of its host layer. In most cases, you’ll want to set a mask layer’s frame to be equal to its host’s bounds.

    Be aware: mask layers do incur an additional performance cost. If the cost becomes too onerous, consider making flattened images of the masked content instead.

  • Gestures

    Gestures are like a higher-level abstraction than the Layer touch handler API. For instance, a pan gesture consumes a series of touch events but does not actually begin until the user moves a certain distance with a specified number of fingers.

    Gestures can also be exclusive: by default, if a gesture recognizes, traditional touch handlers for that subtree will be cancelled. You can control this with the cancelsTouchesInView property. Also by default, if one gesture recognizes, it will prevent all other gestures involved in that touch from recognizing.

    Please refer to the documentation for TouchHandler and TouchesHandler.

  • Variables

  • public var userInteractionEnabled: Bool

    When false, touches that hit this layer or its sublayers are discarded. Defaults to true

  • public var gestures: [GestureType] = []

    Append Gestures to this property to add them to the layer. By default, this is an empty list.

  • public typealias TouchesHandler = [UITouchID: TouchSequence<UITouchID>] -> Bool

  • public typealias TouchHandler = TouchSequence<UITouchID> -> Void

  • public var activeTouchSequences: [UITouchID: TouchSequence<UITouchID>]

  • public var touchesBeganHandler: TouchesHandler?

  • public var touchBeganHandler: TouchHandler?

  • public var touchesMovedHandler: TouchesHandler?

  • public var touchMovedHandler: TouchHandler?

  • public var touchesEndedHandler: TouchesHandler?

  • public var touchEndedHandler: TouchHandler?

  • public var touchesCancelledHandler: TouchesHandler?

  • public var touchCancelledHandler: TouchHandler?

  • public var touchedDescendents: [Layer]

  • Convenience Utilities

  • public private(set) var willBeRemovedSoon: Bool = false

  • public func removeAfterDuration(duration: NSTimeInterval)

    Although the argument is an NSTimeInterval, you can enter seconds here with double resolution.

  • public func fadeOutAndRemoveAfterDuration(duration: NSTimeInterval)

    Although the argument is an NSTimeInterval, you can enter seconds here with double resolution.

  • public var hashValue: Int

    a property that returns a hash for your layer (presumably to compare it with another layer, as in ==)

  • public var description: String

    a readonly property that returns a printable version of your layer

  • public func ==(a: Layer, b: Layer) -> Bool

  • public class func animateWithDuration( duration: NSTimeInterval, animations: () -> Void, completionHandler: (() -> Void)? = nil)

  • public class func animateWithDuration( duration: NSTimeInterval, curve: AnimationCurve, animations: () -> Void, completionHandler: (() -> Void)? = nil)

  • public enum AnimationCurve{}

    AnimationCurve is an enum with the following fields

    public enum AnimationCurve {
        case Linear
        case EaseIn
        case EaseOut
        case EaseInOut