-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
08c9a98
commit 612bbae
Showing
5 changed files
with
172 additions
and
31 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
# ConstraintBuilder | ||
|
||
A description of this package. | ||
Convenience Auto Layout methods, applying constraints through a function builder | ||
|
||
```swift | ||
someView.applyConstraints { | ||
$0.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor) | ||
$0.centerYAnchor.constraint(equalTo: contentView.layoutMarginsGuide.centerYAnchor) | ||
} | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,51 @@ | ||
#if canImport(UIKit) | ||
import UIKit | ||
#elseif canImport(AppKit) | ||
import AppKit | ||
#endif | ||
|
||
@resultBuilder | ||
public struct ConstraintBuilder { | ||
public private(set) var text = "Hello, World!" | ||
static func buildBlock(_ components: NSLayoutConstraint...) -> [NSLayoutConstraint] { | ||
Array(components) | ||
} | ||
static func buildBlock(_ components: [NSLayoutConstraint]) -> [NSLayoutConstraint] { | ||
Array(components) | ||
} | ||
} | ||
|
||
public extension NSLayoutConstraint { | ||
/// Activates all constraints created in the `builder` closure; | ||
/// - Parameter builder: Closure in which all constraints should be created or referenced | ||
/// | ||
/// Typical usage: | ||
/// ```swift | ||
/// NSLayoutConstraint.build { | ||
/// someView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor) | ||
/// someView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor) | ||
/// anotherView.leadingAnchor.constraint(equalTo: someView.trailingAnchor) | ||
/// anotherView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor) | ||
/// } | ||
/// ``` | ||
class func build(@ConstraintBuilder _ builder: () -> [NSLayoutConstraint]) { | ||
activate(builder()) | ||
} | ||
} | ||
|
||
public init() { | ||
} | ||
public protocol ContraintBuildable { | ||
/// Extends all edges to the edges of the provided view | ||
/// - Parameter view: View of which edges should be extended to | ||
func extend(to view: Self) | ||
|
||
/// Aligns center with center of provided view | ||
/// - Parameter view: View of which center should be aligned to | ||
func center(in view: Self) | ||
|
||
/// Extends all edges to the edges of the superview | ||
/// Should result in `assertionFailure` when no superview is available | ||
func extendToSuperview() | ||
|
||
/// Aligns center with center of superview | ||
/// Should result in `assertionFailure` when no superview is available | ||
func centerInSuperview() | ||
} |
94 changes: 94 additions & 0 deletions
94
Sources/ConstraintBuilder/UIView+ConstraintBuildable.swift
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#if canImport(UIKit) | ||
import UIKit | ||
|
||
public protocol UIViewConstraintBuildable: ContraintBuildable { | ||
/// Create and activate constriants with this view as the main subject | ||
/// ```swift | ||
/// view.applyConstraints { | ||
/// $0.leadingAnchor.constraint(equalTo: otherView.leadingAnchor) | ||
/// $0.centerYAnchor.constraint(equalTo: otherView.centerYAnchor) | ||
/// } | ||
/// ``` | ||
/// - Parameter builder: Constraint builder to add the constriants from | ||
func applyConstraints(@ConstraintBuilder _ builder: (UIView) -> [NSLayoutConstraint]) | ||
|
||
/// Extends all edges to provided layout guide | ||
/// - Parameter view: UILayoutGuide of which edges should be extended to | ||
func extend(to layoutGuide: UILayoutGuide) | ||
|
||
/// Aligns center with center of layout guide | ||
/// - Parameter view: UILayoutGuide of which center should be aligned to | ||
func center(in layoutGuide: UILayoutGuide) | ||
|
||
/// Extends all edges to the edges of the superview‘s safe area | ||
/// Should result in `assertionFailure` when no superview is available | ||
func extendToSuperviewSafeArea() | ||
|
||
/// Extends all edges to the edges of the superview‘s layout margins | ||
/// Should result in `assertionFailure` when no superview is available | ||
func extendToSuperviewLayoutMargins() | ||
} | ||
|
||
extension UIView: UIViewConstraintBuildable { | ||
public func applyConstraints(@ConstraintBuilder _ builder: (UIView) -> [NSLayoutConstraint]) { | ||
NSLayoutConstraint.activate(builder(self)) | ||
} | ||
|
||
public func extend(to view: UIView) { | ||
NSLayoutConstraint.build { | ||
leadingAnchor.constraint(equalTo: view.leadingAnchor) | ||
trailingAnchor.constraint(equalTo: view.trailingAnchor) | ||
topAnchor.constraint(equalTo: view.topAnchor) | ||
bottomAnchor.constraint(equalTo: view.bottomAnchor) | ||
} | ||
} | ||
|
||
public func center(in view: UIView) { | ||
NSLayoutConstraint.build { | ||
centerXAnchor.constraint(equalTo: view.centerXAnchor) | ||
centerYAnchor.constraint(equalTo: view.centerYAnchor) | ||
} | ||
} | ||
|
||
public func extend(to layoutGuide: UILayoutGuide) { | ||
NSLayoutConstraint.build { | ||
leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor) | ||
trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor) | ||
topAnchor.constraint(equalTo: layoutGuide.topAnchor) | ||
bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor) | ||
} | ||
} | ||
|
||
public func center(in layoutGuide: UILayoutGuide) { | ||
NSLayoutConstraint.build { | ||
centerXAnchor.constraint(equalTo: layoutGuide.centerXAnchor) | ||
centerYAnchor.constraint(equalTo: layoutGuide.centerYAnchor) | ||
} | ||
} | ||
|
||
/// Use superview if available, `assertionFailure()` if not | ||
private func withSuperview(_ method: (UIView) -> Void) { | ||
guard let superview = superview else { | ||
return assertionFailure() | ||
} | ||
method(superview) | ||
} | ||
|
||
public func extendToSuperview() { | ||
withSuperview(extend(to:)) | ||
} | ||
|
||
public func centerInSuperview() { | ||
withSuperview(center(in:)) | ||
} | ||
|
||
public func extendToSuperviewSafeArea() { | ||
withSuperview { extend(to: $0.safeAreaLayoutGuide) } | ||
} | ||
|
||
public func extendToSuperviewLayoutMargins() { | ||
withSuperview { extend(to: $0.layoutMarginsGuide) } | ||
} | ||
} | ||
|
||
#endif |
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