Last active
August 29, 2015 14:24
-
-
Save danyowdee/0b7a44256582ce7703dc to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// Anchor.swift | |
// AnchorTest | |
// | |
// Created by Jonathan Wight on 7/10/15. | |
// Copyright © 2015 schwa.io. All rights reserved. | |
// | |
#if os(OSX) | |
import AppKit | |
internal typealias View = NSView | |
#elseif os(iOS) | |
import UIKit | |
internal typealias View = UIView | |
#endif | |
public extension View { | |
@objc(d12_anchors) | |
var anchors: Anchors { | |
return Anchors(item:self) | |
} | |
} | |
/// Generator for the actual anchors in a way that makes sense, semantically. | |
@objc(D12Anchors) | |
public class Anchors { | |
internal let item: View | |
internal init(item: View) { | |
self.item = item | |
} | |
// MARK: X–Axis Anchors | |
public var leadingAnchor: LayoutXAxisAnchor { | |
return LayoutXAxisAnchor(item: item, attribute: .Leading) | |
} | |
public var trailingAnchor: LayoutXAxisAnchor { | |
return LayoutXAxisAnchor(item: item, attribute: .Trailing) | |
} | |
public var leftAnchor: LayoutXAxisAnchor { | |
return LayoutXAxisAnchor(item: item, attribute: .Left) | |
} | |
public var rightAnchor: LayoutXAxisAnchor { | |
return LayoutXAxisAnchor(item: item, attribute: .Right) | |
} | |
public var centerXAnchor: LayoutXAxisAnchor { | |
return LayoutXAxisAnchor(item: item, attribute: .CenterX) | |
} | |
// MARK: Y–Axis Anchors | |
public var topAnchor: LayoutYAxisAnchor { | |
return LayoutYAxisAnchor(item: item, attribute: .Top) | |
} | |
public var bottomAnchor: LayoutYAxisAnchor { | |
return LayoutYAxisAnchor(item: item, attribute: .Bottom) | |
} | |
public var centerYAnchor: LayoutYAxisAnchor { | |
return LayoutYAxisAnchor(item: item, attribute: .CenterY) | |
} | |
public var firstBaselineAnchor: LayoutYAxisAnchor { | |
return LayoutYAxisAnchor(item: item, attribute: .FirstBaseline) | |
} | |
public var lastBaselineAnchor: LayoutYAxisAnchor { | |
return LayoutYAxisAnchor(item: item, attribute: .LastBaseline) | |
} | |
// MARK: Size Anchors | |
public var widthAnchor: LayoutDimension { | |
return LayoutDimension(item: item, attribute: .Width) | |
} | |
public var heightAnchor: LayoutDimension { | |
return LayoutDimension(item: item, attribute: .Height) | |
} | |
} | |
// MARK: - | |
/** | |
A LayoutAnchor represents an edge or dimension of a layout item. | |
Its concrete subclasses allow concise creation of constraints. | |
The idea is that instead of invoking | |
+[NSLayoutConstraint constraintWithItem: attribute: relatedBy: toItem: attribute: multiplier: constant:] | |
directly, you can instead do something like this: | |
[myView.topAnchor constraintEqualToAnchor:otherView.topAnchor constant:10]; | |
The `-constraint*` methods are available in multiple flavors to support use of different relations and omission of unused options. | |
*/ | |
@objc(D12LayoutAnchor) | |
public class LayoutAnchor { | |
internal var item: View | |
internal var attribute: NSLayoutAttribute | |
internal init(item: View, attribute: NSLayoutAttribute) { | |
self.item = item | |
self.attribute = attribute | |
} | |
/// Returns a new, inactive constraint of the form thisAnchor = otherAnchor + constant. | |
public func constraintEqualToAnchor(anchor: LayoutAnchor, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .Equal, toItem: anchor.item, attribute: anchor.attribute, multiplier: 1.0, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form thisAnchor ≧ otherAnchor + constant. | |
public func constraintGreaterThanOrEqualToAnchor(anchor: LayoutAnchor, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .GreaterThanOrEqual, toItem: anchor.item, attribute: anchor.attribute, multiplier: 1.0, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form thisAnchor ≦ otherAnchor + constant. | |
public func constraintLessThanOrEqualToAnchor(anchor: LayoutAnchor, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .LessThanOrEqual, toItem: anchor.item, attribute: anchor.attribute, multiplier: 1.0, constant: c) | |
} | |
} | |
// MARK: - Axis-specific subclasses for location anchors | |
/// Subclass for leading/trailing, left/right, and centerX anchors. | |
@objc(D12LayoutXAxisAnchor) | |
public class LayoutXAxisAnchor : LayoutAnchor { | |
} | |
/// Subclass for top/bottom, firstBaseline/lastBaseLine, and centerY anchors | |
@objc(D12LayoutYAxisAnchor) | |
public class LayoutYAxisAnchor : LayoutAnchor { | |
} | |
// MARK: - | |
/** | |
This layout anchor subclass is used for sizes (width & height). | |
*/ | |
@objc(D12LayoutDimension) | |
public class LayoutDimension : LayoutAnchor { | |
/// Returns a new, inactive constraint of the form attribute = constant. | |
public func constraintEqualToConstant(c: CGFloat) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .Equal, toItem: nil, attribute:.NotAnAttribute, multiplier: 1.0, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form attribute ≧ constant. | |
public func constraintGreaterThanOrEqualToConstant(c: CGFloat) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute:.NotAnAttribute, multiplier: 1.0, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form attribute ≦ constant. | |
public func constraintLessThanOrEqualToConstant(c: CGFloat) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .LessThanOrEqual, toItem: nil, attribute:.NotAnAttribute, multiplier: 1.0, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form attribute = otherAnchor.attribute * multiplier + constant. | |
public func constraintEqualToAnchor(anchor: LayoutDimension, multiplier m: CGFloat, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .Equal, toItem: anchor.item, attribute: anchor.attribute, multiplier: m, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form attribute ≧ otherAnchor.attribute * multiplier + constant. | |
public func constraintGreaterThanOrEqualToAnchor(anchor: LayoutDimension, multiplier m: CGFloat, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .GreaterThanOrEqual, toItem: anchor.item, attribute: anchor.attribute, multiplier: m, constant: c) | |
} | |
/// Returns a new, inactive constraint of the form attribute ≦ otherAnchor.attribute * multiplier + constant. | |
public func constraintLessThanOrEqualToAnchor(anchor: LayoutDimension, multiplier m: CGFloat, constant c: CGFloat = 0) -> NSLayoutConstraint { | |
return NSLayoutConstraint(item: item, attribute: attribute, relatedBy: .LessThanOrEqual, toItem: anchor.item, attribute: anchor.attribute, multiplier: m, constant: c) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I hope it goes without saying that this is completely untested: the changes I made to the original were written in GitHub’s online editor.
While most are of cosmetic nature — documentation comments and whitespace — I am not really sure if replacing the duplicated methods by default parameters was a smart move in terms of ObjC compatibility. So I’m not sure if they make it over to Objective–C as two separate methods. (So far, every piece of Swift I wrote didn’t need to be callable by ObjC code.) And I don’t have Xcode on this machine to test that out.