Skip to content

Commit ce55c0f

Browse files
author
Luc Dion
committed
Refactor source code that handle size adjustment.
1 parent 8667180 commit ce55c0f

File tree

10 files changed

+311
-242
lines changed

10 files changed

+311
-242
lines changed

PinLayout.xcodeproj/project.pbxproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
DFB3ECB72062A937005F226B /* PinSafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB3ECB02061602E005F226B /* PinSafeArea.swift */; };
101101
DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */; };
102102
DFCA5F1620111E0B00180CD7 /* UIScrollViewSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFCA5F1420111BCF00180CD7 /* UIScrollViewSpec.swift */; };
103+
DFEAF71220C8081800E33147 /* PinLayoutImpl+Size.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFEAF71120C8081800E33147 /* PinLayoutImpl+Size.swift */; };
103104
DFED154F20852F7E009EF9A7 /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5011E75D88500073BEE /* BasicView.swift */; };
104105
DFED15502085304B009EF9A7 /* AdjustSizeSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C4FF1E75D74000073BEE /* AdjustSizeSpec.swift */; };
105106
DFED155120853085009EF9A7 /* PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */; };
@@ -228,6 +229,7 @@
228229
DFB3ECB02061602E005F226B /* PinSafeArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PinSafeArea.swift; path = Impl/PinSafeArea.swift; sourceTree = "<group>"; };
229230
DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinLayout.swift; sourceTree = "<group>"; };
230231
DFCA5F1420111BCF00180CD7 /* UIScrollViewSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIScrollViewSpec.swift; sourceTree = "<group>"; };
232+
DFEAF71120C8081800E33147 /* PinLayoutImpl+Size.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "PinLayoutImpl+Size.swift"; path = "Impl/PinLayoutImpl+Size.swift"; sourceTree = "<group>"; };
231233
DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "PinLayoutImpl+WrapContent.swift"; path = "Impl/PinLayoutImpl+WrapContent.swift"; sourceTree = "<group>"; };
232234
DFF222CC20B999BD00AC2A84 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = "<group>"; };
233235
DFF222CE20B99A6600AC2A84 /* Types+Description.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Types+Description.swift"; sourceTree = "<group>"; };
@@ -398,6 +400,7 @@
398400
2475B6C71FC37C1C0054CADD /* PinLayoutImpl+Coordinates.swift */,
399401
2475B6C41FC37A900054CADD /* PinLayoutImpl+Layouting.swift */,
400402
2475B6C91FC37C1C0054CADD /* PinLayoutImpl+Relative.swift */,
403+
DFEAF71120C8081800E33147 /* PinLayoutImpl+Size.swift */,
401404
2475B6C81FC37C1C0054CADD /* PinLayoutImpl+Warning.swift */,
402405
DFF222C820B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift */,
403406
DFB3ECB02061602E005F226B /* PinSafeArea.swift */,
@@ -603,7 +606,7 @@
603606
};
604607
249EFE791E64FB4C00165E39 = {
605608
CreatedOnToolsVersion = 8.2.1;
606-
LastSwiftMigration = 0910;
609+
LastSwiftMigration = 0940;
607610
ProvisioningStyle = Automatic;
608611
};
609612
249EFE821E64FB4C00165E39 = {
@@ -849,6 +852,7 @@
849852
DFF222C920B997A500AC2A84 /* PinLayoutImpl+WrapContent.swift in Sources */,
850853
2475B6CF1FC37C570054CADD /* TypesImpl.swift in Sources */,
851854
2475B6D11FC37C8C0054CADD /* UIView+LTR.swift in Sources */,
855+
DFEAF71220C8081800E33147 /* PinLayoutImpl+Size.swift in Sources */,
852856
DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */,
853857
2475B6CC1FC37C1C0054CADD /* PinLayoutImpl+Warning.swift in Sources */,
854858
DF1A5CBB208106A900725EF5 /* UIView+PinLayout.swift in Sources */,

Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PODS:
22
- Nimble (7.0.3)
3-
- PinLayout (1.7.4)
3+
- PinLayout (1.7.5)
44
- Quick (1.2.0)
55
- Reveal-SDK (10)
66
- SwiftLint (0.25.1)
@@ -25,7 +25,7 @@ EXTERNAL SOURCES:
2525

2626
SPEC CHECKSUMS:
2727
Nimble: 7f5a9c447a33002645a071bddafbfb24ea70e0ac
28-
PinLayout: e20545b1fd5110133e0b03bed61f196161af8b36
28+
PinLayout: 94ebd171c7b98482c1b525cfd3ef07aadde9a1e3
2929
Quick: 58d203b1c5e27fff7229c4c1ae445ad7069a7a08
3030
Reveal-SDK: 7869ddf1f902cabbb07a1f0dd06bd25861a126f7
3131
SwiftLint: ce933681be10c3266e82576dad676fa815a602e9

Sources/Impl/PinLayoutImpl+Coordinates.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,6 @@ extension PinLayoutImpl {
367367
}
368368
}
369369

370-
internal func setSize(_ size: CGSize, _ context: Context) -> PinLayout {
371-
setWidth(size.width, { return "\(context())'s width" })
372-
setHeight(size.height, { return "\(context())'s height" })
373-
return self
374-
}
375-
376370
fileprivate func computeCoordinates(_ point: CGPoint, _ layoutSuperview: PView, _ referenceSuperview: PView) -> CGPoint {
377371
if layoutSuperview == referenceSuperview {
378372
return point // same superview => no coordinates conversion required.

Sources/Impl/PinLayoutImpl+Layouting.swift

Lines changed: 141 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -185,155 +185,178 @@ extension PinLayoutImpl {
185185
}
186186

187187
private func computeSize() -> Size {
188-
var width = computeWidth()
189-
var height = computeHeight()
190-
191188
#if os(macOS)
192189
assert(!legacyFitSize && fitType == nil)
193190
#endif
194191

195-
if legacyFitSize {
196-
return computeLegacyFitSize(width: width, height: height)
197-
} else if let fitType = fitType {
198-
var fitWidth = CGFloat.greatestFiniteMagnitude
199-
var fitHeight = CGFloat.greatestFiniteMagnitude
200-
201-
// Apply min/max width/height before calling sizeThatFits() ... and reapply them after.
202-
switch fitType {
203-
case .width, .widthFlexible:
204-
if let width = applyMinMax(toWidth: width) {
205-
fitWidth = width
206-
} else {
207-
fitWidth = view.bounds.width
208-
}
209-
case .height, .heightFlexible:
210-
if let height = applyMinMax(toHeight: height) {
211-
fitHeight = height
212-
} else {
213-
fitHeight = view.bounds.height
214-
}
215-
}
216-
217-
#if os(iOS) || os(tvOS)
218-
let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
219-
#else
220-
let sizeThatFits: CGSize
221-
if #available(OSX 10.10, *) {
222-
if let control = view as? NSControl {
223-
sizeThatFits = control.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
224-
} else {
225-
sizeThatFits = view.intrinsicContentSize
226-
}
227-
} else {
228-
sizeThatFits = view.intrinsicContentSize
229-
}
230-
#endif
192+
var size = resolveSize()
231193

232-
if fitWidth != .greatestFiniteMagnitude {
233-
width = fitType.isFlexible ? sizeThatFits.width : fitWidth
234-
} else {
235-
width = sizeThatFits.width
236-
}
237-
238-
if fitHeight != .greatestFiniteMagnitude {
239-
height = fitType.isFlexible ? sizeThatFits.height : fitHeight
240-
} else {
241-
height = sizeThatFits.height
242-
}
243-
} else if let aspectRatio = _aspectRatio {
244-
if width == nil && height == nil {
245-
warn("aspectRatio won't be applied, neither the width nor the height can be determined.")
246-
} else {
247-
if width != nil && height != nil {
248-
// warn, both are specified
249-
warn("aspectRatio won't be applied, the width and the height are already defined by other PinLayout's properties.")
250-
} else if let width = width, let adjWidth = applyMinMax(toWidth: width) {
251-
height = adjWidth / aspectRatio
252-
} else if let height = height, let adjHeight = applyMinMax(toHeight: height) {
253-
width = adjHeight * aspectRatio
254-
}
194+
if let adjustSizeType = adjustSizeType {
195+
switch adjustSizeType {
196+
case .fitTypeWidth, .fitTypeHeight, .fitTypeWidthFlexible, .fitTypeHeightFlexible:
197+
size = computeSizeToFit(adjustSizeType: adjustSizeType, size: size)
198+
case .fitSizeLegacy:
199+
size = computeLegacyFitSize(size: size)
200+
case .aspectRatio(let ratio):
201+
size = computeAspectRatio(ratio, size: size)
255202
}
256203
}
257204

258-
width = applyMinMax(toWidth: width)
259-
height = applyMinMax(toHeight: height)
260-
261-
if !validateComputedWidth(width) {
262-
width = nil
205+
return validateAndApplyMinMax(toSize: size)
206+
}
207+
208+
private func resolveSize() -> Size {
209+
var size = Size()
210+
211+
// Width
212+
if let width = width {
213+
size.width = width
214+
} else if let left = _left, let right = _right {
215+
size.width = right - left - _marginLeft - _marginRight
216+
} else if shouldKeepViewDimension {
217+
// No width has been specified (and won't be computed by a sizeToFit) => use the current view's width
218+
size.width = Coordinates.getViewRect(view, keepTransform: keepTransform).width
263219
}
264-
265-
if !validateComputedHeight(height) {
266-
height = nil
220+
221+
// Height
222+
if let height = height {
223+
size.height = height
224+
} else if let top = _top, let bottom = _bottom {
225+
size.height = bottom - top - _marginTop - _marginBottom
226+
} else if shouldKeepViewDimension {
227+
size.height = Coordinates.getViewRect(view, keepTransform: keepTransform).height
267228
}
268-
269-
return (width, height)
270-
}
271229

272-
private func computeLegacyFitSize(width: CGFloat?, height: CGFloat?) -> Size {
273-
var width = width
274-
var height = height
230+
return size
231+
}
275232

276-
if width == nil && height == nil {
233+
private func computeLegacyFitSize(size: Size) -> Size {
234+
guard size.width != nil || size.height != nil else {
277235
warn("fitSize() won't be applied, neither the width nor the height can be determined.")
236+
return size
237+
}
238+
239+
var size = size
240+
var fitWidth = CGFloat.greatestFiniteMagnitude
241+
var fitHeight = CGFloat.greatestFiniteMagnitude
242+
243+
if let width = applyMinMax(toWidth: size.width) {
244+
fitWidth = width
245+
}
246+
if let height = applyMinMax(toHeight: size.height) {
247+
fitHeight = height
248+
}
249+
250+
#if os(iOS) || os(tvOS)
251+
let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
252+
#else
253+
let sizeThatFits = view.intrinsicContentSize
254+
#endif
255+
256+
if fitWidth != .greatestFiniteMagnitude && (sizeThatFits.width > fitWidth) {
257+
size.width = fitWidth
258+
} else {
259+
size.width = sizeThatFits.width
260+
}
261+
262+
if fitHeight != .greatestFiniteMagnitude && (sizeThatFits.height > fitHeight) {
263+
size.height = fitHeight
278264
} else {
279-
var fitWidth = CGFloat.greatestFiniteMagnitude
280-
var fitHeight = CGFloat.greatestFiniteMagnitude
265+
size.height = sizeThatFits.height
266+
}
267+
268+
return size
269+
}
270+
271+
private func computeSizeToFit(adjustSizeType: AdjustSizeType, size: Size) -> Size {
272+
var fitWidth = CGFloat.greatestFiniteMagnitude
273+
var fitHeight = CGFloat.greatestFiniteMagnitude
274+
var size = size
281275

282-
if let width = applyMinMax(toWidth: width) {
276+
// Apply min/max width/height before calling sizeThatFits() ... and reapply them after.
277+
switch adjustSizeType {
278+
case .fitTypeWidth, .fitTypeWidthFlexible:
279+
if let width = applyMinMax(toWidth: size.width) {
283280
fitWidth = width
281+
} else {
282+
fitWidth = view.bounds.width
284283
}
285-
if let height = applyMinMax(toHeight: height) {
284+
case .fitTypeHeight, .fitTypeHeightFlexible:
285+
if let height = applyMinMax(toHeight: size.height) {
286286
fitHeight = height
287-
}
288-
289-
#if os(iOS) || os(tvOS)
290-
let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
291-
#else
292-
let sizeThatFits = view.intrinsicContentSize
293-
#endif
294-
295-
if fitWidth != .greatestFiniteMagnitude && (sizeThatFits.width > fitWidth) {
296-
width = fitWidth
297287
} else {
298-
width = sizeThatFits.width
288+
fitHeight = view.bounds.height
299289
}
290+
default:
291+
assertionFailure("Should not occured")
292+
}
300293

301-
if fitHeight != .greatestFiniteMagnitude && (sizeThatFits.height > fitHeight) {
302-
height = fitHeight
294+
#if os(iOS) || os(tvOS)
295+
let sizeThatFits = view.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
296+
#else
297+
let sizeThatFits: CGSize
298+
if #available(OSX 10.10, *) {
299+
if let control = view as? NSControl {
300+
sizeThatFits = control.sizeThatFits(CGSize(width: fitWidth, height: fitHeight))
303301
} else {
304-
height = sizeThatFits.height
302+
sizeThatFits = view.intrinsicContentSize
305303
}
304+
} else {
305+
sizeThatFits = view.intrinsicContentSize
306+
}
307+
#endif
306308

307-
width = applyMinMax(toWidth: width)
308-
height = applyMinMax(toHeight: height)
309+
if fitWidth != .greatestFiniteMagnitude {
310+
size.width = adjustSizeType.isFlexible ? sizeThatFits.width : fitWidth
311+
} else {
312+
size.width = sizeThatFits.width
313+
}
309314

310-
if !validateComputedWidth(width) {
311-
width = nil
312-
}
315+
if fitHeight != .greatestFiniteMagnitude {
316+
size.height = adjustSizeType.isFlexible ? sizeThatFits.height : fitHeight
317+
} else {
318+
size.height = sizeThatFits.height
319+
}
313320

314-
if !validateComputedHeight(height) {
315-
height = nil
316-
}
321+
return size
322+
}
323+
324+
private func computeAspectRatio(_ aspectRatio: CGFloat, size: Size) -> Size {
325+
guard size.width != nil || size.height != nil else {
326+
warn("aspectRatio won't be applied, neither the width nor the height can be determined.")
327+
return size
328+
}
329+
guard size.width == nil || size.height == nil else {
330+
warn("aspectRatio won't be applied, the width and the height are already defined by other PinLayout's properties.")
331+
return size
317332
}
318333

319-
return (width, height)
334+
if let width = size.width, let adjustedWidth = applyMinMax(toWidth: width) {
335+
return Size(width: adjustedWidth, height: adjustedWidth / aspectRatio)
336+
} else if let height = size.height, let adjustedHeight = applyMinMax(toHeight: height) {
337+
return Size(width: adjustedHeight * aspectRatio, height: adjustedHeight)
338+
} else {
339+
assertionFailure("Should not occurs, all cases should be handled by guards above")
340+
return size
341+
}
320342
}
321-
322-
private func computeWidth() -> CGFloat? {
323-
var newWidth: CGFloat?
324-
325-
if let width = width {
326-
newWidth = width
327-
} else if let left = _left, let right = _right {
328-
newWidth = right - left - _marginLeft - _marginRight
329-
} else if shouldKeepViewDimension {
330-
// No width has been specified (and won't be computed by a sizeToFit) => use the current view's width
331-
newWidth = view.bounds.width
343+
344+
private func validateAndApplyMinMax(toSize size: Size) -> Size {
345+
var size = size
346+
size.width = applyMinMax(toWidth: size.width)
347+
size.height = applyMinMax(toHeight: size.height)
348+
349+
if !validateComputedWidth(size.width) {
350+
size.width = nil
332351
}
333-
334-
return newWidth
352+
353+
if !validateComputedHeight(size.height) {
354+
size.height = nil
355+
}
356+
357+
return size
335358
}
336-
359+
337360
private func applyMinMax(toWidth width: CGFloat?) -> CGFloat? {
338361
var result = width
339362

@@ -386,20 +409,6 @@ extension PinLayoutImpl {
386409
return rect
387410
}
388411

389-
private func computeHeight() -> CGFloat? {
390-
var newHeight: CGFloat?
391-
392-
if let height = height {
393-
newHeight = height
394-
} else if let top = _top, let bottom = _bottom {
395-
newHeight = bottom - top - _marginTop - _marginBottom
396-
} else if shouldKeepViewDimension {
397-
newHeight = view.bounds.height
398-
}
399-
400-
return newHeight
401-
}
402-
403412
private func applyMinMax(toHeight height: CGFloat?) -> CGFloat? {
404413
var result = height
405414

0 commit comments

Comments
 (0)