Skip to content

Commit 98c90b1

Browse files
dharmik-ymlmpospese
authored andcommitted
Added constrainSize extension
1 parent 00b3e23 commit 98c90b1

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// UIView+constrainSize.swift
3+
// YCoreUI
4+
//
5+
// Created by Dharmik Ghelani on 17/10/22.
6+
// Copyright © 2022 Y Media Labs. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
extension UIView {
12+
/// Constrain the receiving view with given size
13+
/// - Parameters:
14+
/// - size: size of view to constrain to
15+
/// - relation: relation to evaluate (towards sibling) (default `.equal`)
16+
/// - priority: constraint priority (default `.required`)
17+
/// - isActive: whether to activate the constraint or not (default `true`)
18+
/// - Returns: The created layout constraint
19+
@discardableResult public func constrainSize(
20+
_ size: CGSize,
21+
relatedBy relation: NSLayoutConstraint.Relation = .equal,
22+
priority: UILayoutPriority = .required,
23+
isActive: Bool = true
24+
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
25+
let widthConstraint = constrain(
26+
.widthAnchor,
27+
relatedBy: relation,
28+
constant: size.width,
29+
priority: priority,
30+
isActive: isActive
31+
)
32+
33+
let heightConstraint = constrain(
34+
.heightAnchor,
35+
relatedBy: relation,
36+
constant: size.height,
37+
priority: priority,
38+
isActive: isActive
39+
)
40+
41+
return [.width: widthConstraint, .height: heightConstraint]
42+
}
43+
44+
/// Constrain the receiving view with width and heigh
45+
/// - Parameters:
46+
/// - width: width of view to constrain to
47+
/// - height: height of view to constrain to
48+
/// - relation: relation to evaluate (towards sibling) (default `.equal`)
49+
/// - priority: constraint priority (default `.required`)
50+
/// - isActive: whether to activate the constraint or not (default `true`)
51+
/// - Returns: The created layout constraint
52+
@discardableResult public func constrainSize(
53+
width: CGFloat,
54+
height: CGFloat,
55+
relatedBy relation: NSLayoutConstraint.Relation = .equal,
56+
priority: UILayoutPriority = .required,
57+
isActive: Bool = true
58+
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
59+
constrainSize(CGSize(width: width, height: height))
60+
}
61+
62+
/// Constrain the receiving view with given dimension
63+
/// - Parameters:
64+
/// - dimension: dimension of view to constrain to
65+
/// - relation: relation to evaluate (towards sibling) (default `.equal`)
66+
/// - priority: constraint priority (default `.required`)
67+
/// - isActive: whether to activate the constraint or not (default `true`)
68+
/// - Returns: The created layout constraint
69+
@discardableResult public func constrainSize(
70+
_ dimension: CGFloat,
71+
relatedBy relation: NSLayoutConstraint.Relation = .equal,
72+
priority: UILayoutPriority = .required,
73+
isActive: Bool = true
74+
) -> [NSLayoutConstraint.Attribute: NSLayoutConstraint] {
75+
constrainSize(CGSize(width: dimension, height: dimension))
76+
}
77+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
//
2+
// UIView+constrainSizeTests.swift
3+
// YCoreUITests
4+
//
5+
// Created by Dharmik Ghelani on 17/10/22.
6+
// Copyright © 2022 Y Media Labs. All rights reserved.
7+
//
8+
9+
import XCTest
10+
@testable import YCoreUI
11+
12+
final class UIViewConstrainSizeTests: XCTestCase {
13+
private lazy var randomSize = {
14+
CGSize(
15+
width: self.randomFloat,
16+
height: self.randomFloat
17+
)
18+
}()
19+
20+
private lazy var randomDimension: CGFloat = {
21+
randomFloat
22+
}()
23+
24+
func testSize() {
25+
let sut = makeSUT()
26+
27+
XCTAssert(sut.translatesAutoresizingMaskIntoConstraints)
28+
29+
let sizeAttributes: [
30+
(NSLayoutConstraint.Attribute, CGFloat)
31+
] = [
32+
(.width, randomSize.width),
33+
(.height, randomSize.height)
34+
]
35+
36+
let constraints = sut.constrainSize(randomSize)
37+
38+
sizeAttributes.forEach {
39+
guard let constraint = constraints[$0.0] else {
40+
XCTFail("Expected to have constraint for give attribute")
41+
return
42+
}
43+
44+
XCTAssertEqual(constraint.firstItem as? UIView, sut)
45+
XCTAssertEqual(constraint.firstAttribute, $0.0)
46+
XCTAssertNil(constraint.secondItem)
47+
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
48+
XCTAssertEqual(constraint.multiplier, 1)
49+
XCTAssertEqual(constraint.constant, $0.1)
50+
XCTAssertEqual(constraint.priority, .required)
51+
XCTAssert(constraint.isActive)
52+
}
53+
}
54+
55+
func testWidthAndHeight() {
56+
let sut = makeSUT()
57+
58+
XCTAssert(sut.translatesAutoresizingMaskIntoConstraints)
59+
60+
let sizeAttributes: [
61+
(NSLayoutConstraint.Attribute, CGFloat)
62+
] = [
63+
(.width, randomSize.width),
64+
(.height, randomSize.height)
65+
]
66+
67+
let constraints = sut.constrainSize(width: randomSize.width, height: randomSize.height)
68+
69+
sizeAttributes.forEach {
70+
guard let constraint = constraints[$0.0] else {
71+
XCTFail("Expected to have constraint for give attribute")
72+
return
73+
}
74+
75+
XCTAssertEqual(constraint.firstItem as? UIView, sut)
76+
XCTAssertEqual(constraint.firstAttribute, $0.0)
77+
XCTAssertNil(constraint.secondItem)
78+
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
79+
XCTAssertEqual(constraint.multiplier, 1)
80+
XCTAssertEqual(constraint.constant, $0.1)
81+
XCTAssertEqual(constraint.priority, .required)
82+
XCTAssert(constraint.isActive)
83+
}
84+
}
85+
86+
func testDimension() {
87+
let sut = makeSUT()
88+
89+
XCTAssert(sut.translatesAutoresizingMaskIntoConstraints)
90+
91+
let randomDimension = randomFloat
92+
93+
let sizeAttributes: [
94+
(NSLayoutConstraint.Attribute, CGFloat)
95+
] = [
96+
(.width, randomDimension),
97+
(.height, randomDimension)
98+
]
99+
100+
let constraints = sut.constrainSize(randomDimension)
101+
102+
sizeAttributes.forEach {
103+
guard let constraint = constraints[$0.0] else {
104+
XCTFail("Expected to have constraint for give attribute")
105+
return
106+
}
107+
108+
XCTAssertEqual(constraint.firstItem as? UIView, sut)
109+
XCTAssertEqual(constraint.firstAttribute, $0.0)
110+
XCTAssertNil(constraint.secondItem)
111+
XCTAssertEqual(constraint.secondAttribute, .notAnAttribute)
112+
XCTAssertEqual(constraint.multiplier, 1)
113+
XCTAssertEqual(constraint.constant, $0.1)
114+
XCTAssertEqual(constraint.priority, .required)
115+
XCTAssert(constraint.isActive)
116+
}
117+
}
118+
}
119+
120+
extension UIViewConstrainSizeTests {
121+
func makeSUT(
122+
file: StaticString = #filePath,
123+
line: UInt = #line
124+
) -> UIView {
125+
let sut = UIView()
126+
127+
trackForMemoryLeak(sut, file: file, line: line)
128+
return sut
129+
}
130+
131+
var randomFloat: CGFloat {
132+
CGFloat.random(in: 0...500)
133+
}
134+
}

0 commit comments

Comments
 (0)