Skip to content

Commit

Permalink
Merge pull request #10 from Weebly/width-and-height-methods
Browse files Browse the repository at this point in the history
Easy Width & Height Constraints
  • Loading branch information
eddiekaiger authored Jun 25, 2018
2 parents 1208c91 + 8dba31a commit 1316819
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 42 deletions.
4 changes: 2 additions & 2 deletions AnchorKit.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "AnchorKit"
s.version = "2.1.0"
s.version = "2.1.1"
s.summary = "A Swifty anchor-based API for AutoLayout."

s.description = <<-DESC
Expand All @@ -20,7 +20,7 @@ Pod::Spec.new do |s|
s.osx.deployment_target = "10.11"
s.tvos.deployment_target = "9.0"

s.source = { :git => "https://github.com/Weebly/AnchorKit.git", :tag => "v2.1.0" }
s.source = { :git => "https://github.com/Weebly/AnchorKit.git", :tag => "v2.1.1" }
s.requires_arc = true
s.source_files = "AnchorKit/Source/*.swift"

Expand Down
6 changes: 5 additions & 1 deletion AnchorKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0900;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Eddie Kaiger";
TargetAttributes = {
C01EC55F1E8F002500BEBB0F = {
Expand Down Expand Up @@ -496,13 +496,15 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
Expand Down Expand Up @@ -559,13 +561,15 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
65 changes: 28 additions & 37 deletions AnchorKit/Source/Anchorable+Constraints.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,78 +118,69 @@ extension Anchorable {

/**
Constrains the edges of the current item to another item by creating and activating the leading, trailing, top, and bottom constraints.
- parameter relation: The relation for all of the constraints. If you want to use `.equal`, you can use `constrainEdges(to:priority:)` instead.
- parameter relation: The relation for all of the constraints. Default is `.equal`.
- parameter item: The item to which to constrain.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the leading, trailing, top, and bottom anchors.
*/
@discardableResult
public func constrainEdges<AnchorableType: Anchorable>(_ relation: Relation, to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
public func constrainEdges<AnchorableType: Anchorable>(_ relation: Relation = .equal, to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return constrain(.leading, .trailing, .top, .bottom, relation: relation, to: item, priority: priority)
}

/**
Constrains the edges of the current item to another item by creating and activating the leading, trailing, top, and bottom constraints. If you want to use this with a relation, use `constrainEdges(_:to:priority:)`.
- parameter item: The item to which to constrain.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the leading, trailing, top, and bottom anchors.
*/
@discardableResult
public func constrainEdges<AnchorableType: Anchorable>(to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return constrainEdges(.equal, to: item, priority: priority)
}

// MARK: - Center Constraints

/**
Convenience method for centering the current item in another item by creating the centerX and centerY constraints. If you want to use this with a relation, use `constrainCenter(_:to:priority:)`.
- parameter item: The item in which to center the current item.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the centerX and centerY anchors.
*/
@discardableResult
public func constrainCenter<AnchorableType: Anchorable>(to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return constrainCenter(.equal, to: item, priority: priority)
}

/**
Convenience method for centering the current item in another item by creating the centerX and centerY constraints.
- parameter relation: The relation for both constraints. If you want to use `.equal`, you can also just use `constrainCenter(to:priority:)` instead.
- parameter relation: The relation for both constraints. Default is `.equal`.
- parameter item: The item in which to center the current item.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the centerX and centerY anchors.
*/
@discardableResult
public func constrainCenter<AnchorableType: Anchorable>(_ relation: Relation, to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
public func constrainCenter<AnchorableType: Anchorable>(_ relation: Relation = .equal, to item: AnchorableType, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return constrain(.centerX, .centerY, relation: relation, to: item, priority: priority)
}

// MARK: - Size Constraints

/**
Constrains the width and height of the current item to a specific size.
- parameter relation: The relation for all of the constraints. Default is `.equal`.
- parameter size: The size to which to constrain.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the width and height anchors.
*/
@discardableResult
public func constrain(to size: CGSize, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return constrain(.equal, to: size, priority: priority)
public func constrain(_ relation: Relation = .equal, to size: CGSize, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return [
constrain(.width, relation: relation, toConstant: size.width, priority: priority),
constrain(.height, relation: relation, toConstant: size.height, priority: priority)
]
}

/**
Constrains the width and height of the current item to a specific size.
- parameter relation: The relation for all of the constraints. If you want to use `.equal`, you can use `constrain(to:priority:)` instead.
- parameter size: The size to which to constrain.
Constrains the height of the current item to a specific value.
- parameter relation: The relation for the constraint. Default is `.equal`.
- parameter height: The height to which to constrain.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraints for the width and height anchors.
- returns: The newly created and activated constraint for height anchor.
*/
@discardableResult
public func constrain(_ relation: Relation, to size: CGSize, priority: LayoutPriority = .required) -> [NSLayoutConstraint] {
return [
constrain(.width, relation: relation, toConstant: size.width, priority: priority),
constrain(.height, relation: relation, toConstant: size.height, priority: priority)
]
public func constrainHeight(_ relation: Relation = .equal, to height: CGFloatRepresentable, priority: LayoutPriority = .required) -> NSLayoutConstraint {
return constrain(.height, relation: relation, toConstant: height, priority: priority)
}

/**
Constrains the width of the current item to a specific value.
- parameter relation: The relation for the constraint. Default is `.equal`.
- parameter width: The width to which to constrain.
- parameter priority: The layout priority to set for the constraints. Default is `.required`.
- returns: The newly created and activated constraint for width anchor.
*/
@discardableResult
public func constrainWidth(_ relation: Relation = .equal, to width: CGFloatRepresentable, priority: LayoutPriority = .required) -> NSLayoutConstraint {
return constrain(.width, relation: relation, toConstant: width, priority: priority)
}

#if os(iOS) || os(tvOS)
Expand Down
38 changes: 38 additions & 0 deletions AnchorKitTests/Anchorable_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,10 @@ class Anchorable_Tests: XCTestCase {
func testConstrainToSize() {
let constraints = view1.constrain(to: CGSize(width: 20, height: 30), priority: .medium)
XCTAssertEqual(constraints[0].firstAnchor, view1.widthAnchor)
XCTAssertNil(constraints[0].secondAnchor)
XCTAssertEqual(constraints[0].constant, 20)
XCTAssertEqual(constraints[1].firstAnchor, view1.heightAnchor)
XCTAssertNil(constraints[1].secondAnchor)
XCTAssertEqual(constraints[1].constant, 30)
}

Expand All @@ -376,6 +378,42 @@ class Anchorable_Tests: XCTestCase {

// MARK: - Width and Height

func testConstrainHeight() {
let constraint = view1.constrainHeight(to: 20)
XCTAssertEqual(constraint.firstAnchor, view1.heightAnchor)
XCTAssertNil(constraint.secondAnchor)
XCTAssertEqual(constraint.constant, 20)
}

func testConstrainHeight_withOptions() {
let constraint = view1.constrainHeight(.greaterThanOrEqual, to: 12, priority: .low)
XCTAssertEqual(constraint.relation, .greaterThanOrEqual)
XCTAssertEqual(constraint.layoutPriority, .low)
}

func testConstrainToHeight_defaults() {
let constraint = view1.constrainHeight(to: 20)
testDefaults(for: constraint, constant: 20)
}

func testConstrainWidth() {
let constraint = view1.constrainWidth(to: 20)
XCTAssertEqual(constraint.firstAnchor, view1.widthAnchor)
XCTAssertNil(constraint.secondAnchor)
XCTAssertEqual(constraint.constant, 20)
}

func testConstrainWidth_withOptions() {
let constraint = view1.constrainWidth(.greaterThanOrEqual, to: 12, priority: .medium)
XCTAssertEqual(constraint.relation, .greaterThanOrEqual)
XCTAssertEqual(constraint.layoutPriority, .medium)
}

func testConstrainToWidth_defaults() {
let constraint = view1.constrainWidth(to: 20)
testDefaults(for: constraint, constant: 20)
}

func testUpdateWidth() {
let constraints = view1.constrain(.width, .height, toConstant: 100)
view1.updateWidth(200)
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ myView.constrainEdges(to: anotherView).insetVertical(20).insetHorizontal(30)

// Set height/width equal to a constant
myView.constrain(.height, .width, toConstant: 200)
myView.constrainWidth(to: 42)

// Set the height/width equal to a CGSize
myView.constrain(to: CGSize(width: 100, height: 200))
Expand Down Expand Up @@ -159,6 +160,10 @@ Constrain an anchor of an item to a constant. This is is especially useful (and
````swift
myView.constrain(.height, toConstant: 200)
myBoxView.constrain(.width, .height, toConstant: 50) // Creates a box

// Even easier:
myView.constrainHeight(to: 42)
myView.constrainWidth(to: 60)
````

Calling this method with a single anchor will implicitly return `NSLayoutConstraint`. Otherwise, the return type is `[NSLayoutConstraint]`. The full signatures of these methods are shown below.
Expand Down

0 comments on commit 1316819

Please sign in to comment.