Skip to content

Added constrainSize extension #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .jazzy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ xcodebuild_arguments:
- -sdk
- iphonesimulator
- -destination
- 'platform=iOS Simulator,name=iPhone 13'
- 'platform=iOS Simulator,name=iPhone 14'
77 changes: 77 additions & 0 deletions Sources/YCoreUI/Extensions/UIKit/UIView+constrainSize.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// UIView+constrainSize.swift
// YCoreUI
//
// Created by Dharmik Ghelani on 17/10/22.
// Copyright © 2022 Y Media Labs. All rights reserved.
//

import UIKit

extension UIView {
/// Constrain the receiving view with given size
/// - Parameters:
/// - size: size of view to constrain to
/// - relation: relation to evaluate (towards size) (default `.equal`)
/// - priority: constraint priority (default `.required`)
/// - isActive: whether to activate the constraint or not (default `true`)
/// - Returns: The created layout constraint
@discardableResult public func constrainSize(
_ size: CGSize,
relatedBy relation: NSLayoutConstraint.Relation = .equal,
priority: UILayoutPriority = .required,
isActive: Bool = true
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
let widthConstraint = constrain(
.widthAnchor,
relatedBy: relation,
constant: size.width,
priority: priority,
isActive: isActive
)

let heightConstraint = constrain(
.heightAnchor,
relatedBy: relation,
constant: size.height,
priority: priority,
isActive: isActive
)

return [.width: widthConstraint, .height: heightConstraint]
}

/// Constrain the receiving view with width and heigh
/// - Parameters:
/// - width: width of view to constrain to
/// - height: height of view to constrain to
/// - relation: relation to evaluate (towards width and height) (default `.equal`)
/// - priority: constraint priority (default `.required`)
/// - isActive: whether to activate the constraint or not (default `true`)
/// - Returns: The created layout constraint
@discardableResult public func constrainSize(
width: CGFloat,
height: CGFloat,
relatedBy relation: NSLayoutConstraint.Relation = .equal,
priority: UILayoutPriority = .required,
isActive: Bool = true
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
constrainSize(CGSize(width: width, height: height))
}

/// Constrain the receiving view with given dimension
/// - Parameters:
/// - dimension: dimension of view to constrain to
/// - relation: relation to evaluate (towards dimension) (default `.equal`)
/// - priority: constraint priority (default `.required`)
/// - isActive: whether to activate the constraint or not (default `true`)
/// - Returns: The created layout constraint
@discardableResult public func constrainSize(
_ dimension: CGFloat,
relatedBy relation: NSLayoutConstraint.Relation = .equal,
priority: UILayoutPriority = .required,
isActive: Bool = true
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
constrainSize(CGSize(width: dimension, height: dimension))
}
}
125 changes: 125 additions & 0 deletions Tests/YCoreUITests/Extensions/UIKit/UIView+constrainSizeTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//
// UIView+constrainSizeTests.swift
// YCoreUITests
//
// Created by Dharmik Ghelani on 17/10/22.
// Copyright © 2022 Y Media Labs. All rights reserved.
//

import XCTest
@testable import YCoreUI

final class UIViewConstrainSizeTests: XCTestCase {
let randomSize = CGSize(width: 150, height: 200)

func testSize() {
let sut = makeSUT()

let sizeAttributes: [
(NSLayoutConstraint.Attribute, CGFloat)
] = [
(.width, randomSize.width),
(.height, randomSize.height)
]

let constraints = sut.constrainSize(randomSize)

XCTAssertFalse(sut.translatesAutoresizingMaskIntoConstraints)

sizeAttributes.forEach {
guard let constraint = constraints[$0.0] else {
XCTFail("Expected to have constraint for give attribute")
return
}

XCTAssertEqual(constraint.firstItem as? UIView, sut)
XCTAssertEqual(constraint.firstAttribute, $0.0)
XCTAssertNil(constraint.secondItem)
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
XCTAssertEqual(constraint.multiplier, 1)
XCTAssertEqual(constraint.constant, $0.1)
XCTAssertEqual(constraint.priority, .required)
XCTAssert(constraint.isActive)
}
}

func testWidthAndHeight() {
let sut = makeSUT()

XCTAssert(sut.translatesAutoresizingMaskIntoConstraints)

let sizeAttributes: [
(NSLayoutConstraint.Attribute, CGFloat)
] = [
(.width, randomSize.width),
(.height, randomSize.height)
]

let constraints = sut.constrainSize(width: randomSize.width, height: randomSize.height)

XCTAssertFalse(sut.translatesAutoresizingMaskIntoConstraints)

sizeAttributes.forEach {
guard let constraint = constraints[$0.0] else {
XCTFail("Expected to have constraint for give attribute")
return
}

XCTAssertEqual(constraint.firstItem as? UIView, sut)
XCTAssertEqual(constraint.firstAttribute, $0.0)
XCTAssertNil(constraint.secondItem)
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
XCTAssertEqual(constraint.multiplier, 1)
XCTAssertEqual(constraint.constant, $0.1)
XCTAssertEqual(constraint.priority, .required)
XCTAssert(constraint.isActive)
}
}

func testDimension() {
let sut = makeSUT()

XCTAssert(sut.translatesAutoresizingMaskIntoConstraints)

let randomDimension = 100.0

let sizeAttributes: [
(NSLayoutConstraint.Attribute, CGFloat)
] = [
(.width, randomDimension),
(.height, randomDimension)
]

let constraints = sut.constrainSize(randomDimension)

XCTAssertFalse(sut.translatesAutoresizingMaskIntoConstraints)

sizeAttributes.forEach {
guard let constraint = constraints[$0.0] else {
XCTFail("Expected to have constraint for give attribute")
return
}

XCTAssertEqual(constraint.firstItem as? UIView, sut)
XCTAssertEqual(constraint.firstAttribute, $0.0)
XCTAssertNil(constraint.secondItem)
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
XCTAssertEqual(constraint.multiplier, 1)
XCTAssertEqual(constraint.constant, $0.1)
XCTAssertEqual(constraint.priority, .required)
XCTAssert(constraint.isActive)
}
}
}

extension UIViewConstrainSizeTests {
func makeSUT(
file: StaticString = #filePath,
line: UInt = #line
) -> UIView {
let sut = UIView()

trackForMemoryLeak(sut, file: file, line: line)
return sut
}
}