Skip to content

Commit 84b4f7a

Browse files
authored
Merge pull request #158 from layoutBox/sizeToFit
Add method sizeToFit()
2 parents 09d350a + 3bc5d3e commit 84b4f7a

12 files changed

+74
-41
lines changed

Example/PinLayoutSample/UI/Common/BasicView.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,8 @@ class BasicView: UIView {
6464

6565
return newSize
6666
}
67+
68+
override func sizeToFit() {
69+
pin.width(35).height(45)
70+
}
6771
}

README.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
3939

4040
### Recent changes/features
4141
* :star: PinLayout can now layout CALayer. See [CALayer Support](#calayer_support) for more information.
42+
* :star: PinLayout is in the Top 10 of Swift Layout frameworks on [Awesome Swift](https://swift.libhunt.com/categories/714-layout)
4243
* :star: PinLayout has moved to the **[layoutBox](https://github.com/layoutBox)** organization. See other **[layoutBox](https://github.com/layoutBox)** projects.
4344
* :star: Add `wrapContent()` methods that adjust view's width and height to wrap all its subviews. See [wrapContent](#wrapContent) for more information.
4445
* :star: PinLayout now support macOS. See [macOS Support](#macos_support) for more information.
@@ -58,6 +59,7 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
5859
* [Anchors](#anchors)
5960
* [Relative positioning](#relative_positioning)
6061
* [Width, height and size](#width_height_size)
62+
* [Adjusting size](#adjusting_size)
6163
* [minWidth, maxWidth, minHeight, maxHeight](#minmax_width_height_size)
6264
* [Aspect Ratio](#aspect_ratio)
6365
* [Margins](#margins)
@@ -705,18 +707,23 @@ Set the view’s size to match the referenced view’s size
705707

706708
<br/>
707709

708-
<a name="sizeToFit"></a>
709-
### sizeToFit
710+
<a name="adjusting_size"></a>
711+
### Adjusting size
710712

711-
**Method:**
713+
PinLayout has methods to adjust the view’s size based on their content.
712714

713-
* **`sizeToFit(_ fitType: FitType)`**
714-
The method adjust the view's size based on the view's `sizeThatFits()` method result.
715-
PinLayout will adjust either the view's width or height based on the `fitType` parameter value.
716-
717-
Notes:
718-
* If margin rules apply, margins will be applied when determining the reference dimension (width/height).
719-
* The resulting size will always respect `minWidth` / `maxWidth` / `minHeight` / `maxHeight`.
715+
The resulting size will always respect [`minWidth`/`maxWidth`/`minHeight`/`maxHeight`](#minmax_width_height_size) values.
716+
717+
718+
**Methods:**
719+
720+
* **`sizeToFit()`**
721+
The method adjust the view's size based on the result of the method `UIView.sizeToFit()`. Particularly useful for controls/views that have an intrinsic size (label, button, ...).
722+
723+
* **`sizeToFit(: FitType)`**
724+
The method adjust the view's size based on the result of the method `sizeThatFits(:CGSize)`.
725+
PinLayout will adjust either the view's width or height based on the `fitType` parameter value.
726+
If margins are specified, they will be applied before calling the view's `sizeThatFits(:CGSize)` method.
720727

721728
**Parameter `fitType`:** Identify the reference dimension (width / height) that will be used to adjust the view's size.
722729

@@ -736,6 +743,9 @@ The method adjust the view's size based on the view's `sizeThatFits()` method re
736743
###### Usage examples:
737744

738745
```swift
746+
// Adjust the view's size based on the result of `UIView.sizeToFit()` and center it.
747+
view.pin.center().sizeToFit()
748+
739749
// Adjust the view's size based on a width of 100 pixels.
740750
// The resulting width will always match the pinned property `width(100)`.
741751
view.pin.width(100).sizeToFit(.width)

Sources/Impl/PinLayout+Layouting.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ extension PinLayout {
201201
switch adjustSizeType {
202202
case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible:
203203
size = computeSizeToFit(adjustSizeType: adjustSizeType, size: size)
204+
case .sizeToFit:
205+
size = computeSizeToFit(size: size)
204206
case .fitSizeLegacy:
205207
size = computeLegacyFitSize(size: size)
206208
case .aspectRatio(let ratio):
@@ -236,6 +238,17 @@ extension PinLayout {
236238
return size
237239
}
238240

241+
private func computeSizeToFit(size: Size) -> Size {
242+
guard let sizeCalculableView = view as? SizeCalculable else {
243+
assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType")
244+
return size
245+
}
246+
sizeCalculableView.sizeToFit()
247+
248+
let viewRect = view.getRect(keepTransform: keepTransform)
249+
return Size(width: viewRect.width, height: viewRect.height)
250+
}
251+
239252
private func computeLegacyFitSize(size: Size) -> Size {
240253
guard let sizeCalculableView = view as? SizeCalculable else {
241254
assertionFailure("Should not occurs, protocol conformance is checked before assigning adjustSizeType")

Sources/PinLayout+Size.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ enum AdjustSizeType {
2929
case fitTypeWidthFlexible
3030
case fitTypeHeightFlexible
3131

32+
case sizeToFit
33+
3234
case fitSizeLegacy
3335
case aspectRatio(CGFloat)
3436

@@ -44,7 +46,9 @@ enum AdjustSizeType {
4446

4547
internal var requiresSizeCalculable: Bool {
4648
switch self {
47-
case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible, .fitSizeLegacy:
49+
case .fitTypeWidth, .fitTypeHeight,
50+
.fitTypeWidthFlexible, .fitTypeHeightFlexible,
51+
.sizeToFit, .fitSizeLegacy:
4852
return true
4953
case .aspectRatio(_):
5054
return false
@@ -217,6 +221,11 @@ extension PinLayout {
217221
return setAdjustSizeType(fitType.toAdjustSizeType(), { return "sizeToFit(\(fitType.description))" })
218222
}
219223

224+
@discardableResult
225+
public func sizeToFit() -> PinLayout {
226+
return setAdjustSizeType(.sizeToFit, { return "sizeToFit()" })
227+
}
228+
220229
#if os(iOS) || os(tvOS)
221230
@available(*, deprecated, message: "fitSize() is deprecated, please use sizeToFit(fitType: FitType)")
222231
@discardableResult
@@ -246,7 +255,7 @@ extension PinLayout {
246255
warnWontBeApplied("the aspectRatio (\(ratio)) must be greater than zero.", context)
247256
return self
248257
} else if type.requiresSizeCalculable, !(view is SizeCalculable) {
249-
warnWontBeApplied("the view must conform to protocol SizeCalculable for it's size to be computed.", context)
258+
warnWontBeApplied("PinLayout cannot comptute this view's size. This type of views doesn't conform to the protocol SizeCalculable.", context)
250259
return self
251260
}
252261
}
@@ -262,6 +271,8 @@ extension PinLayout {
262271
switch adjustSizeType {
263272
case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible:
264273
conflict = "sizeToFit(\(adjustSizeType.toFitType()!.description))."
274+
case .sizeToFit:
275+
conflict = "sizeToFit()"
265276
case .fitSizeLegacy:
266277
conflict = "fitSize()"
267278
case .aspectRatio(let ratio):

Tests/BasicView.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class BasicView: PView {
5555
override func sizeThatFits(_ size: CGSize) -> CGSize {
5656
return _sizeThatFits(size)
5757
}
58+
59+
override func sizeToFit() {
60+
pin.width(35).height(45)
61+
}
5862
#endif
5963

6064
fileprivate func _sizeThatFits(_ size: CGSize) -> CGSize {
@@ -81,7 +85,7 @@ extension BasicView: SizeCalculable {
8185
}
8286

8387
func sizeToFit() {
84-
// Do nothing
88+
pin.width(35).height(45)
8589
}
8690
}
8791
#endif

Tests/Common/AdjustSizeSpec.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,8 @@ class AdjustSizeSpec: QuickSpec {
4444
- bViewChild
4545
*/
4646

47-
beforeSuite {
48-
_pinlayoutSetUnitTest(scale: 2)
49-
}
50-
5147
beforeEach {
48+
_pinlayoutSetUnitTest(scale: 2)
5249
Pin.lastWarningText = nil
5350

5451
viewController = PViewController()
@@ -862,6 +859,18 @@ class AdjustSizeSpec: QuickSpec {
862859
expect(aView.frame).to(beCloseTo(CGRect(x: 140.0, y: 100.0, width: 50.0, height: 32.0), within: 0.5))
863860
}
864861
}
862+
863+
//
864+
// sizeToFit()
865+
//
866+
describe("the result of the sizeToFit()") {
867+
it("should adjust the aView") {
868+
_pinlayoutSetUnitTest(scale: 3)
869+
870+
aView.pin.sizeToFit().center()
871+
expect(aView.frame).to(beCloseTo(CGRect(x: 182.6667, y: 177.6667, width: 35.0, height: 45.0), within: 0.1))
872+
}
873+
}
865874
#endif
866875
}
867876
}

Tests/Common/AspectRatioTests.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,8 @@ class AspectRatioTests: QuickSpec {
4040
- imageView
4141
*/
4242

43-
beforeSuite {
44-
_pinlayoutSetUnitTest(scale: 2)
45-
}
46-
4743
beforeEach {
44+
_pinlayoutSetUnitTest(scale: 2)
4845
Pin.lastWarningText = nil
4946

5047
viewController = PViewController()

Tests/Common/JustifyAlignSpec.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,9 @@ class JustifyAlignSpec: QuickSpec {
3232
|
3333
- aView
3434
*/
35-
36-
beforeSuite {
37-
_pinlayoutSetUnitTest(scale: 2)
38-
}
3935

4036
beforeEach {
37+
_pinlayoutSetUnitTest(scale: 2)
4138
Pin.lastWarningText = nil
4239

4340
viewController = PViewController()

Tests/Common/LayoutMethodSpec.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ class LayoutMethodSpec: QuickSpec {
3333
- aView
3434
*/
3535

36-
beforeSuite {
37-
_pinlayoutSetUnitTest(scale: 2)
38-
}
39-
4036
beforeEach {
37+
_pinlayoutSetUnitTest(scale: 2)
4138
Pin.lastWarningText = nil
4239
Pin.logMissingLayoutCalls = false
4340

Tests/Common/MinMaxWidthHeightSpec.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,8 @@ class MinMaxWidthHeightSpec: QuickSpec {
3333
- aView
3434
*/
3535

36-
beforeSuite {
37-
_pinlayoutSetUnitTest(scale: 2)
38-
}
39-
4036
beforeEach {
37+
_pinlayoutSetUnitTest(scale: 2)
4138
Pin.lastWarningText = nil
4239

4340
viewController = PViewController()

0 commit comments

Comments
 (0)