Skip to content

[CM-1012] Add constrainAspectRatio method to UIView extension. #38

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 12 commits into from
Dec 16, 2022
Merged
37 changes: 37 additions & 0 deletions Sources/YCoreUI/Extensions/UIKit/UIView+constrainAspectRatio.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// UIView+constrainAspectRatio.swift
// YCoreUI
//
// Created by Dev Karan on 14/12/22.
// Copyright © 2022 Y Media Labs. All rights reserved.
//

import UIKit

extension UIView {
/// Constrain the aspect ratio for the receiving view.
/// - Parameters:
/// - ratio: aspect ratio
/// - offset: offset to apply (default `.zero`)
/// - relation: relation to evaluate (towards ratio) (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 constrainAspectRatio(
_ ratio: CGFloat,
offset: CGFloat = 0,
relatedBy relation: NSLayoutConstraint.Relation = .equal,
priority: UILayoutPriority = .required,
isActive: Bool = true
) -> NSLayoutConstraint {
constrain(
.widthAnchor,
to: heightAnchor,
relatedBy: relation,
multiplier: ratio,
constant: offset,
priority: priority,
isActive: isActive
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ extension UIView {
return [.width: widthConstraint, .height: heightConstraint]
}

/// Constrain the receiving view with width and heigh
/// Constrain the receiving view with width and height
/// - Parameters:
/// - width: width of view to constrain to
/// - height: height of view to constrain to
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// UIView+constrainAspectRatioTests.swift
// YCoreUI
//
// Created by Dev Karan on 14/12/22.
// Copyright © 2022 Y Media Labs. All rights reserved.
//

import XCTest
import YCoreUI

final class UIViewContrainAspectRatioTests: XCTestCase {
func test_constrainAspectRatio_deliversDefaultValues() {
// Arrange
let sut = makeSUT()
// Act
let constraint = sut.constrainAspectRatio(0.5)
// Assert
XCTAssertEqual(constraint.constant, .zero)
XCTAssertEqual(constraint.priority, .required)
XCTAssertTrue(constraint.isActive)
XCTAssertEqual(constraint.relation, .equal)
XCTAssertEqual(constraint.firstAttribute, .width)
XCTAssertEqual(constraint.secondAttribute, .height)
}

func test_constrainAspectRatio_translatesAutoresizingMaskIntoConstraintsIsFalse() {
// Arrange
let sut = makeSUT()
// Act
sut.constrainAspectRatio(0.5)
// Assert
XCTAssertFalse(sut.translatesAutoresizingMaskIntoConstraints)
}

func test_constrainAspectRatio_multiplierAndRatioMatches() {
// Arrange
let sut = makeSUT()
let ratio = 0.5
// Act
let constraint = sut.constrainAspectRatio(ratio)
// Assert
XCTAssertEqual(constraint.multiplier, ratio)
}

func test_constrainAspectRatio_resizesSUTWithGivenRatio() {
// Arrange
let containerView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 500, height: 500)))
let sut = makeSUT()
containerView.addSubview(sut)

let ratio: CGFloat = 0.7
let height: CGFloat = 300
sut.constrain(.heightAnchor, constant: height)
// Act
sut.constrainAspectRatio(ratio)
sut.layoutIfNeeded()
// Assert
XCTAssertEqual(sut.bounds.width, ratio * sut.bounds.height)
XCTAssertEqual(sut.bounds.height, height)
}
}

private extension UIViewContrainAspectRatioTests {
func makeSUT(
file: StaticString = #filePath,
line: UInt = #line
) -> UIView {
let sut = UIView()
trackForMemoryLeak(sut, file: file, line: line)
return sut
}
}