diff --git a/README.md b/README.md index e8ce0e5..76e6feb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## SwiftAutoLayout -SwiftAutoLayout is a tiny DSL for Autolayout (~90 LOC), intended to provide a more declarative way to express layout constraints. Here's a quick example: +SwiftAutoLayout is a tiny DSL for Autolayout intended to provide a more declarative way to express layout constraints. Here's a quick example: ```swift // this: @@ -23,6 +23,8 @@ SwiftAutoLayout allows you to more effectively communicate the intent of a const Layout attributes are defined as properties added in extensions of `UIView` and `UILayoutGuide` on iOS and `NSView` and `NSLayoutGuide` on OS X. For example, `UIView.width` and `UIView.height` represent `NSLayoutAttribute.Width` and `NSLayoutAttribute.Height`, respectively. +Layout guides (conforming to `UILayoutSupport`) in `UIViewController` are also supported using the `topLayoutGuideTop`, `topLayoutGuideBottom`, `bottomLayoutGuideTop`, and `bottomLayoutGuideBottom` properties. + ### Relations Relations are expressed using the overloaded operators `==` (`NSLayoutRelation.Equal`), `>=` (`NSLayoutRelation.GreaterThanOrEqual`), and `<=` (`NSLayoutRelation.LessThanOrEqual`). diff --git a/SwiftAutoLayout/SwiftAutoLayout.swift b/SwiftAutoLayout/SwiftAutoLayout.swift index 5914ebb..4932589 100644 --- a/SwiftAutoLayout/SwiftAutoLayout.swift +++ b/SwiftAutoLayout/SwiftAutoLayout.swift @@ -90,23 +90,43 @@ public func <=(lhs: LayoutItem, rhs: CGFloat) -> NSLayoutConstraint { return lhs.constrain(rhs, relation: .LessThanOrEqual) } +private func layoutItem(item: AnyObject, _ attribute: NSLayoutAttribute) -> LayoutItem { + return LayoutItem(item: item, attribute: attribute, multiplier: 1.0, constant: 0.0) +} + public extension LayoutRegion { - private func layoutItem(attribute: NSLayoutAttribute) -> LayoutItem { - return LayoutItem(item: self, attribute: attribute, multiplier: 1.0, constant: 0.0) + public var left: LayoutItem { return layoutItem(self, .Left) } + public var right: LayoutItem { return layoutItem(self, .Right) } + public var top: LayoutItem { return layoutItem(self, .Top) } + public var bottom: LayoutItem { return layoutItem(self, .Bottom) } + public var leading: LayoutItem { return layoutItem(self, .Leading) } + public var trailing: LayoutItem { return layoutItem(self, .Trailing) } + public var width: LayoutItem { return layoutItem(self, .Width) } + public var height: LayoutItem { return layoutItem(self, .Height) } + public var centerX: LayoutItem { return layoutItem(self, .CenterX) } + public var centerY: LayoutItem { return layoutItem(self, .CenterY) } + public var baseline: LayoutItem { return layoutItem(self, .Baseline) } +} + +#if os(iOS) +public extension UIViewController { + public var topLayoutGuideTop: LayoutItem { + return layoutItem(topLayoutGuide, .Top) + } + + public var topLayoutGuideBottom: LayoutItem { + return layoutItem(topLayoutGuide, .Bottom) + } + + public var bottomLayoutGuideTop: LayoutItem { + return layoutItem(bottomLayoutGuide, .Top) } - public var left: LayoutItem { return layoutItem(.Left) } - public var right: LayoutItem { return layoutItem(.Right) } - public var top: LayoutItem { return layoutItem(.Top) } - public var bottom: LayoutItem { return layoutItem(.Bottom) } - public var leading: LayoutItem { return layoutItem(.Leading) } - public var trailing: LayoutItem { return layoutItem(.Trailing) } - public var width: LayoutItem { return layoutItem(.Width) } - public var height: LayoutItem { return layoutItem(.Height) } - public var centerX: LayoutItem { return layoutItem(.CenterX) } - public var centerY: LayoutItem { return layoutItem(.CenterY) } - public var baseline: LayoutItem { return layoutItem(.Baseline) } + public var bottomLayoutGuideBottom: LayoutItem { + return layoutItem(bottomLayoutGuide, .Bottom) + } } +#endif infix operator ~ { associativity left precedence 120 } diff --git a/SwiftAutoLayoutTests/SwiftAutoLayoutTests.swift b/SwiftAutoLayoutTests/SwiftAutoLayoutTests.swift index c08f72f..f13ad3c 100644 --- a/SwiftAutoLayoutTests/SwiftAutoLayoutTests.swift +++ b/SwiftAutoLayoutTests/SwiftAutoLayoutTests.swift @@ -4,11 +4,19 @@ import XCTest import SwiftAutoLayout +#if os(iOS) +private class ViewController: UIViewController { + private override func loadView() { + self.view = UIView(frame: CGRectZero) + } +} +#endif + class SwiftAutoLayoutTests: XCTestCase { let view1 = View(frame: CGRectZero) let view2 = View(frame: CGRectZero) - func testAttributeValues() { + func testViewAttributeValues() { XCTAssertEqual(view1.left.attribute, NSLayoutAttribute.Left) XCTAssertEqual(view1.right.attribute, NSLayoutAttribute.Right) XCTAssertEqual(view1.top.attribute, NSLayoutAttribute.Top) @@ -22,6 +30,17 @@ class SwiftAutoLayoutTests: XCTestCase { XCTAssertEqual(view1.baseline.attribute, NSLayoutAttribute.Baseline) } + #if os(iOS) + func testViewControllerAttributeValues() { + let viewController = ViewController() + print(viewController.view) // Load the view + XCTAssertEqual(viewController.topLayoutGuideTop.attribute, NSLayoutAttribute.Top) + XCTAssertEqual(viewController.topLayoutGuideBottom.attribute, NSLayoutAttribute.Bottom) + XCTAssertEqual(viewController.bottomLayoutGuideTop.attribute, NSLayoutAttribute.Top) + XCTAssertEqual(viewController.bottomLayoutGuideBottom.attribute, NSLayoutAttribute.Bottom) + } + #endif + func testEqual() { let constraint = view1.left == view2.right; XCTAssertEqual(constraint.firstItem as? View, view1)