Skip to content

Commit

Permalink
Merge branch 'main' into move-view-layout-tem
Browse files Browse the repository at this point in the history
# Conflicts:
#	Sources/Layout/LayoutItem.swift
  • Loading branch information
tinder-garricnahapetian committed Oct 25, 2023
2 parents 219e752 + 5db7d32 commit dac47a4
Show file tree
Hide file tree
Showing 356 changed files with 1,967 additions and 1,423 deletions.
142 changes: 3 additions & 139 deletions Sources/Layout/AnchorAttribute.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// swiftlint:disable:this file_name
//
// All Contributions by Match Group
//
Expand All @@ -9,149 +10,12 @@

import UIKit

// swiftlint:disable file_types_order

internal protocol AnchorAttribute {

associatedtype AnchorType: AnyObject

var attributeType: AnchorAttributeType { get }
var attribute: NSLayoutConstraint.Attribute { get }
}

// swiftlint:enable file_types_order

internal enum AnchorAttributeType {

case xAxisAnchor, yAxisAnchor, dimension
}

public enum XAxisAttribute: AnchorAttribute {
public enum XAxisAttribute {

case left, centerX, right, leading, trailing

internal typealias AnchorType = NSLayoutXAxisAnchor

internal var attributeType: AnchorAttributeType {
.xAxisAnchor
}

internal var attribute: NSLayoutConstraint.Attribute {
switch self {
case .left:
return .left
case .centerX:
return .centerX
case .right:
return .right
case .leading:
return .leading
case .trailing:
return .trailing
}
}
}

public enum YAxisAttribute: AnchorAttribute {
public enum YAxisAttribute {

case top, centerY, firstBaseline, lastBaseline, bottom

internal typealias AnchorType = NSLayoutYAxisAnchor

internal var attributeType: AnchorAttributeType {
.yAxisAnchor
}

internal var attribute: NSLayoutConstraint.Attribute {
switch self {
case .top:
return .top
case .centerY:
return .centerY
case .firstBaseline:
return .firstBaseline
case .lastBaseline:
return .lastBaseline
case .bottom:
return .bottom
}
}
}

public enum DimensionAttribute: AnchorAttribute {

case width, height

internal typealias AnchorType = NSLayoutDimension

internal var attributeType: AnchorAttributeType {
.dimension
}

internal var attribute: NSLayoutConstraint.Attribute {
switch self {
case .width:
return .width
case .height:
return .height
}
}
}

extension LayoutAnchoring {

internal func anchor<T: AnchorAttribute>(for attribute: T) -> NSLayoutAnchor<T.AnchorType> {
// swiftlint:disable force_cast
switch attribute.attributeType {
case .xAxisAnchor:
let attribute: XAxisAttribute = attribute as! XAxisAttribute
return xAnchor(for: attribute) as! NSLayoutAnchor<T.AnchorType>
case .yAxisAnchor:
let attribute: YAxisAttribute = attribute as! YAxisAttribute
return yAnchor(for: attribute) as! NSLayoutAnchor<T.AnchorType>
case .dimension:
let attribute: DimensionAttribute = attribute as! DimensionAttribute
return sizeAnchor(for: attribute) as! NSLayoutAnchor<T.AnchorType>
}
// swiftlint:enable force_cast
}

private func xAnchor(for attribute: XAxisAttribute) -> NSLayoutXAxisAnchor {
switch attribute {
case .left:
return left
case .centerX:
return centerX
case .right:
return right
case .leading:
return leading
case .trailing:
return trailing
}
}

private func yAnchor(for attribute: YAxisAttribute) -> NSLayoutYAxisAnchor {
switch attribute {
case .top:
return top
case .centerY:
return centerY
case .firstBaseline:
return firstBaseline
case .lastBaseline:
return lastBaseline
case .bottom:
return bottom
}
}

private func sizeAnchor(for attribute: DimensionAttribute) -> NSLayoutDimension {
switch attribute {
case .width:
return width
case .height:
return height
}
}
}
25 changes: 25 additions & 0 deletions Sources/Layout/Collection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// All Contributions by Match Group
//
// Copyright © 2023 Tinder (Match Group, LLC)
//
// Licensed under the Match Group Modified 3-Clause BSD License.
// See https://github.com/Tinder/Layout/blob/main/LICENSE for license information.
//

extension Collection where Element == Layout {

/// Activates all constraints of each instance
@preconcurrency
@MainActor
public func activate() {
forEach { $0.activate() }
}

/// Deactivates all constraints of each instance
@preconcurrency
@MainActor
public func deactivate() {
forEach { $0.deactivate() }
}
}
78 changes: 26 additions & 52 deletions Sources/Layout/Layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -419,18 +419,26 @@ public final class Layout { // swiftlint:disable:this type_body_length
guard views.count >= 2,
let first = views.first
else { return self }
var anchor: NSLayoutAnchor<XAxisAttribute.AnchorType> = first.anchor(for: direction.attributes.1)
for view in views.dropFirst() {
adding(
view
.anchor(for: direction.attributes.0)
.constraint(equalTo: anchor, constant: spacing)
.withPriority(priority)
)
anchor = view.anchor(for: direction.attributes.1)
switch direction {
case .leadingToTrailing:
var anchor: NSLayoutXAxisAnchor = first.trailing
for view in views.dropFirst() {
adding(view.leading.constraint(equalTo: anchor, constant: spacing).withPriority(priority))
anchor = view.trailing
}
case .leftToRight:
var anchor: NSLayoutXAxisAnchor = first.right
for view in views.dropFirst() {
adding(view.left.constraint(equalTo: anchor, constant: spacing).withPriority(priority))
anchor = view.right
}
}
for attribute: YAxisAttribute in alignment {
adding(equalAttribute(attribute, views).withPriority(priority))
let firstAnchor: NSLayoutYAxisAnchor = first.anchor(for: attribute)
let constraints: [NSLayoutConstraint] = views
.dropFirst()
.map { $0.anchor(for: attribute).constraint(equalTo: firstAnchor) }
adding(constraints.withPriority(priority))
}
return self
}
Expand All @@ -451,18 +459,17 @@ public final class Layout { // swiftlint:disable:this type_body_length
guard views.count >= 2,
let first = views.first
else { return self }
var anchor: NSLayoutAnchor<YAxisAttribute.AnchorType> = first.anchor(for: YAxisAttribute.bottom)
var anchor: NSLayoutYAxisAnchor = first.bottom
for view in views.dropFirst() {
adding(
view
.anchor(for: YAxisAttribute.top)
.constraint(equalTo: anchor, constant: spacing)
.withPriority(priority)
)
anchor = view.anchor(for: YAxisAttribute.bottom)
adding(view.top.constraint(equalTo: anchor, constant: spacing).withPriority(priority))
anchor = view.bottom
}
for attribute: XAxisAttribute in alignment {
adding(equalAttribute(attribute, views).withPriority(priority))
let firstAnchor: NSLayoutXAxisAnchor = first.anchor(for: attribute)
let constraints: [NSLayoutConstraint] = views
.dropFirst()
.map { $0.anchor(for: attribute).constraint(equalTo: firstAnchor) }
adding(constraints.withPriority(priority))
}
return self
}
Expand Down Expand Up @@ -585,22 +592,6 @@ public final class Layout { // swiftlint:disable:this type_body_length
])
}

@discardableResult
private func equalAttribute<T: AnchorAttribute>(
_ attribute: T,
_ views: [UIView]
) -> [NSLayoutConstraint] {
guard views.count >= 2,
let first = views.first
else { return [] }
let firstAnchor: NSLayoutAnchor<T.AnchorType> = first.anchor(for: attribute)
return views.dropFirst().map { view in
view
.anchor(for: attribute)
.constraint(equalTo: firstAnchor)
}
}

/// Adds LayoutItems
///
/// - Note:
Expand Down Expand Up @@ -673,20 +664,3 @@ public final class Layout { // swiftlint:disable:this type_body_length
view?.updateConstraintsIfNeeded()
}
}

extension Collection where Element == Layout {

/// Activates all constraints of each instance
@preconcurrency
@MainActor
public func activate() {
forEach { $0.activate() }
}

/// Deactivates all constraints of each instance
@preconcurrency
@MainActor
public func deactivate() {
forEach { $0.deactivate() }
}
}
79 changes: 3 additions & 76 deletions Sources/Layout/LayoutAnchoring.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// swiftlint:disable:this file_name
//
// All Contributions by Match Group
//
Expand All @@ -9,27 +10,7 @@

import UIKit

@preconcurrency
@MainActor
public protocol LayoutAnchoring {

var left: NSLayoutXAxisAnchor { get }
var centerX: NSLayoutXAxisAnchor { get }
var right: NSLayoutXAxisAnchor { get }
var leading: NSLayoutXAxisAnchor { get }
var trailing: NSLayoutXAxisAnchor { get }

var top: NSLayoutYAxisAnchor { get }
var centerY: NSLayoutYAxisAnchor { get }
var firstBaseline: NSLayoutYAxisAnchor { get }
var bottom: NSLayoutYAxisAnchor { get }
var lastBaseline: NSLayoutYAxisAnchor { get }

var width: NSLayoutDimension { get }
var height: NSLayoutDimension { get }
}

extension UIView: LayoutAnchoring {
extension UIView {

public var left: NSLayoutXAxisAnchor { leftAnchor }
public var centerX: NSLayoutXAxisAnchor { centerXAnchor }
Expand All @@ -47,7 +28,7 @@ extension UIView: LayoutAnchoring {
public var height: NSLayoutDimension { heightAnchor }
}

extension UILayoutGuide: LayoutAnchoring {
extension UILayoutGuide: LayoutBoundary, LayoutCenter, LayoutSize {

public var left: NSLayoutXAxisAnchor { leftAnchor }
public var centerX: NSLayoutXAxisAnchor { centerXAnchor }
Expand All @@ -65,13 +46,6 @@ extension UILayoutGuide: LayoutAnchoring {
public var height: NSLayoutDimension { heightAnchor }
}

extension UILayoutSupport {

public var top: NSLayoutYAxisAnchor { topAnchor }
public var bottom: NSLayoutYAxisAnchor { bottomAnchor }
public var height: NSLayoutDimension { heightAnchor }
}

// swiftlint:disable function_default_parameter_at_end

extension NSLayoutXAxisAnchor {
Expand Down Expand Up @@ -114,51 +88,4 @@ extension NSLayoutYAxisAnchor {
}
}

extension NSLayoutDimension {

public func constraint(
is relation: NSLayoutConstraint.Relation = .equal,
to anchor: NSLayoutDimension,
constant: CGFloat = 0
) -> NSLayoutConstraint {
switch relation {
case .equal:
return constraint(equalTo: anchor, constant: constant)
case .greaterThanOrEqual:
return constraint(greaterThanOrEqualTo: anchor, constant: constant)
case .lessThanOrEqual:
return constraint(lessThanOrEqualTo: anchor, constant: constant)
@unknown default:
return constraint(equalTo: anchor, constant: constant)
}
}

public func constraint(
is relation: NSLayoutConstraint.Relation = .equal,
_ constant: CGFloat
) -> NSLayoutConstraint {
switch relation {
case .equal:
return constraint(equalToConstant: constant)
case .greaterThanOrEqual:
return constraint(greaterThanOrEqualToConstant: constant)
case .lessThanOrEqual:
return constraint(lessThanOrEqualToConstant: constant)
@unknown default:
return constraint(equalToConstant: constant)
}
}
}

// swiftlint:enable function_default_parameter_at_end

extension UIViewController {

public var safeTop: NSLayoutYAxisAnchor {
view.safeAreaLayoutGuide.top
}

public var safeBottom: NSLayoutYAxisAnchor {
view.safeAreaLayoutGuide.bottom
}
}
Loading

0 comments on commit dac47a4

Please sign in to comment.