Skip to content

Commit 71ecf66

Browse files
author
Luc Dion
authored
Merge pull request #48 from mirego/relative_visibles
Update relative methods signatures when specifying multiple relative views
2 parents 88ff81e + fa0612f commit 71ecf66

File tree

12 files changed

+738
-585
lines changed

12 files changed

+738
-585
lines changed

Example/PinLayoutSample/UI/Tests/Intro/IntroView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,6 @@ class IntroView: BaseView {
6868
logo.pin.topLeft().size(100).margin(topLayoutGuide + 10, 10, 10)
6969
segmented.pin.right(of: logo, aligned: .top).right().marginHorizontal(10)
7070
textLabel.pin.below(of: segmented, aligned: .left).width(of: segmented).pinEdges().marginTop(10).sizeToFit()
71-
separatorView.pin.below(of: logo, textLabel, aligned: .left).right(to: segmented.edge.right).marginTop(10)
71+
separatorView.pin.below(of: [logo, textLabel], aligned: .left).right(to: segmented.edge.right).marginTop(10)
7272
}
7373
}

Example/PinLayoutSample/UI/Tests/TableViewExample/Cells/MethodCell.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class MethodCell: UITableViewCell {
4848

4949
iconImageView.pin.topLeft().size(30).margin(margin)
5050
nameLabel.pin.right(of: iconImageView, aligned: .center).right().marginHorizontal(margin).sizeToFit()
51-
descriptionLabel.pin.below(of: iconImageView, nameLabel).left().right().margin(margin).sizeToFit()
51+
descriptionLabel.pin.below(of: [iconImageView, nameLabel]).left().right().margin(margin).sizeToFit()
5252

5353
return CGSize(width: frame.width, height: descriptionLabel.frame.maxY + margin)
5454
}

PinLayout.xcodeproj/project.pbxproj

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
242E8DC31EED5AB2005935FB /* RelativePositionMultipleViewsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 242E8DC11EED5982005935FB /* RelativePositionMultipleViewsSpec.swift */; };
1515
244C6E151E776A0C0074FC74 /* MarginsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 244C6E141E776A0C0074FC74 /* MarginsSpec.swift */; };
1616
244DF3031EF46F6C0090508B /* InfoTVOS.plist in Resources */ = {isa = PBXBuildFile; fileRef = 244DF3011EF46F670090508B /* InfoTVOS.plist */; };
17-
244DF3061EF46FC20090508B /* PinLayoutTVOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 244DF3041EF46FB90090508B /* PinLayoutTVOS.h */; };
17+
244DF3061EF46FC20090508B /* PinLayoutTVOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 244DF3041EF46FB90090508B /* PinLayoutTVOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
1818
245302071ED05FD000E13F29 /* AccurencyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 245302061ED05FD000E13F29 /* AccurencyTests.swift */; };
1919
2469C4FC1E74855D00073BEE /* PinEdgeCoordinateSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C4FB1E74855D00073BEE /* PinEdgeCoordinateSpec.swift */; };
2020
2469C5001E75D74000073BEE /* AdjustSizeSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C4FF1E75D74000073BEE /* AdjustSizeSpec.swift */; };
2121
2469C5021E75D88500073BEE /* BasicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5011E75D88500073BEE /* BasicView.swift */; };
2222
2469C5041E75DB7600073BEE /* RectNimbleMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2469C5031E75DB7600073BEE /* RectNimbleMatcher.swift */; };
2323
246D36481E6C46F50050F202 /* PinPointCoordinatesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 246D36471E6C46F50050F202 /* PinPointCoordinatesSpec.swift */; };
2424
2482908C1E78CFFC00667D08 /* RelativePositionSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */; };
25+
24949A281EF550E2003643D3 /* PinLayoutImpl+Relative.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A271EF550E2003643D3 /* PinLayoutImpl+Relative.swift */; };
26+
24949A2A1EF551D6003643D3 /* PinLayoutImpl+Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A291EF551D6003643D3 /* PinLayoutImpl+Coordinates.swift */; };
27+
24949A2C1EF55216003643D3 /* PinLayoutImpl+Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2B1EF55216003643D3 /* PinLayoutImpl+Warning.swift */; };
28+
24949A2E1EF69474003643D3 /* PinLayout+Filters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */; };
2529
249EFE841E64FB4C00165E39 /* PinLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 249EFE7A1E64FB4C00165E39 /* PinLayout.framework */; };
2630
249EFE891E64FB4C00165E39 /* PinLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249EFE881E64FB4C00165E39 /* PinLayoutTests.swift */; };
2731
24A9782E1EE845BB002BD0F1 /* Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A9782D1EE845BB002BD0F1 /* Coordinates.swift */; };
@@ -72,6 +76,10 @@
7276
2469C5031E75DB7600073BEE /* RectNimbleMatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RectNimbleMatcher.swift; sourceTree = "<group>"; };
7377
246D36471E6C46F50050F202 /* PinPointCoordinatesSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinPointCoordinatesSpec.swift; sourceTree = "<group>"; };
7478
2482908B1E78CFFC00667D08 /* RelativePositionSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelativePositionSpec.swift; sourceTree = "<group>"; };
79+
24949A271EF550E2003643D3 /* PinLayoutImpl+Relative.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PinLayoutImpl+Relative.swift"; sourceTree = "<group>"; };
80+
24949A291EF551D6003643D3 /* PinLayoutImpl+Coordinates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PinLayoutImpl+Coordinates.swift"; sourceTree = "<group>"; };
81+
24949A2B1EF55216003643D3 /* PinLayoutImpl+Warning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PinLayoutImpl+Warning.swift"; sourceTree = "<group>"; };
82+
24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PinLayout+Filters.swift"; sourceTree = "<group>"; };
7583
249EFE7A1E64FB4C00165E39 /* PinLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PinLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7684
249EFE831E64FB4C00165E39 /* PinLayoutTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PinLayoutTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
7785
249EFE881E64FB4C00165E39 /* PinLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinLayoutTests.swift; sourceTree = "<group>"; };
@@ -146,6 +154,7 @@
146154
isa = PBXGroup;
147155
children = (
148156
DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */,
157+
24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */,
149158
DFA06B031E8B38B300B6D5E7 /* Impl */,
150159
DF11A3741E834181008B33E5 /* Supporting Files */,
151160
);
@@ -188,6 +197,9 @@
188197
children = (
189198
24A9782D1EE845BB002BD0F1 /* Coordinates.swift */,
190199
DFC97CA41E8A8EB3001545D5 /* PinLayoutImpl.swift */,
200+
24949A291EF551D6003643D3 /* PinLayoutImpl+Coordinates.swift */,
201+
24949A271EF550E2003643D3 /* PinLayoutImpl+Relative.swift */,
202+
24949A2B1EF55216003643D3 /* PinLayoutImpl+Warning.swift */,
191203
DF11A3701E833F03008B33E5 /* TypesImpl.swift */,
192204
);
193205
name = Impl;
@@ -241,7 +253,6 @@
241253
249EFE761E64FB4C00165E39 /* Frameworks */,
242254
249EFE771E64FB4C00165E39 /* Headers */,
243255
249EFE781E64FB4C00165E39 /* Resources */,
244-
9045643059E57F984AB8FF52 /* Tailor */,
245256
);
246257
buildRules = (
247258
);
@@ -344,23 +355,6 @@
344355
};
345356
/* End PBXResourcesBuildPhase section */
346357

347-
/* Begin PBXShellScriptBuildPhase section */
348-
9045643059E57F984AB8FF52 /* Tailor */ = {
349-
isa = PBXShellScriptBuildPhase;
350-
buildActionMask = 2147483647;
351-
files = (
352-
);
353-
inputPaths = (
354-
);
355-
name = Tailor;
356-
outputPaths = (
357-
);
358-
runOnlyForDeploymentPostprocessing = 0;
359-
shellPath = /bin/sh;
360-
shellScript = "#if hash tailor 2>/dev/null; then\n#tailor\n#else\n# echo \"warning: Please install Tailor from https://tailor.sh\"\n#fi";
361-
};
362-
/* End PBXShellScriptBuildPhase section */
363-
364358
/* Begin PBXSourcesBuildPhase section */
365359
244DF2F31EF46C500090508B /* Sources */ = {
366360
isa = PBXSourcesBuildPhase;
@@ -374,9 +368,13 @@
374368
buildActionMask = 2147483647;
375369
files = (
376370
DF11A3711E833F03008B33E5 /* TypesImpl.swift in Sources */,
371+
24949A2C1EF55216003643D3 /* PinLayoutImpl+Warning.swift in Sources */,
377372
DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */,
373+
24949A2E1EF69474003643D3 /* PinLayout+Filters.swift in Sources */,
378374
DFC97CA51E8A8EB3001545D5 /* PinLayoutImpl.swift in Sources */,
379375
24A9782E1EE845BB002BD0F1 /* Coordinates.swift in Sources */,
376+
24949A281EF550E2003643D3 /* PinLayoutImpl+Relative.swift in Sources */,
377+
24949A2A1EF551D6003643D3 /* PinLayoutImpl+Coordinates.swift in Sources */,
380378
);
381379
runOnlyForDeploymentPostprocessing = 0;
382380
};
@@ -572,7 +570,6 @@
572570
DYLIB_INSTALL_NAME_BASE = "@rpath";
573571
INFOPLIST_FILE = Sources/Info.plist;
574572
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
575-
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
576573
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
577574
PRODUCT_BUNDLE_IDENTIFIER = com.mirego.PinLayout;
578575
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -594,7 +591,6 @@
594591
DYLIB_INSTALL_NAME_BASE = "@rpath";
595592
INFOPLIST_FILE = Sources/Info.plist;
596593
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
597-
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
598594
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
599595
PRODUCT_BUNDLE_IDENTIFIER = com.mirego.PinLayout;
600596
PRODUCT_NAME = "$(TARGET_NAME)";

README.md

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -399,16 +399,23 @@ PinLayout also has methods to position relative to other views. The view can be
399399

400400
**Methods:**
401401

402-
* `above(of relativeViews: UIView...)`
403-
Position the view above the specified views. One or many relative views can be specied. This method is similar to pinning the view’s bottom edge.
404-
* `below(of relativeViews: UIView...)`
405-
Position the view below the specified view. One or many relative views can be specied. This method is similar to pinning the view’s top edge.
406-
* `left(of relativeViews: UIView...)`
407-
Position the view left of the specified view. One or many relative views can be specied. This method is similar to pinning the view’s right edge.
408-
* `right(of relativeViews: UIView...)`
409-
Position the view right of the specified view. One or many relative views can be specied. This method is similar to pinning the view’s left edge.
402+
* `above(of: UIView)`
403+
`above(of: [UIView])`
404+
Position the view above the specified view(s). One or many relative views can be specied. This method is similar to pinning the view’s bottom edge.
405+
406+
* `below(of: UIView)`
407+
`below(of: [UIView])`
408+
Position the view below the specified view(s). One or many relative views can be specied. This method is similar to pinning the view’s top edge.
409+
410+
* `left(of: UIView)`
411+
`left(of: [UIView])`
412+
Position the view left of the specified view(s). One or many relative views can be specied. This method is similar to pinning the view’s right edge.
413+
414+
* `right(of: UIView)`
415+
`right(of: [UIView])`
416+
Position the view right of the specified view(s). One or many relative views can be specied. This method is similar to pinning the view’s left edge.
410417

411-
:pushpin: **Multiple relative views**: If for example a call to `below(of ...) specify multiple relative views, the view will be layouted below *ALL* these views.
418+
:pushpin: **Multiple relative views**: If for example a call to `below(of: [...]) specify multiple relative views, the view will be layouted below *ALL* these views.
412419

413420
:pushpin: These methods **set the position of a view's edge**: top, left, bottom or right. For example `below(of ...)` set the view's top edge, `right(of ...) set the view's left edge, ...
414421

@@ -417,7 +424,7 @@ Position the view right of the specified view. One or many relative views can be
417424
###### Usage examples:
418425
```swift
419426
view.pin.left(of: view2)
420-
view.pin.below(of: view2, view3, view4)
427+
view.pin.below(of: [view2, view3, view4])
421428
view.pin.left(of: view1).above(of: view2).below(of: view3).right(of: view4)
422429
```
423430

@@ -451,14 +458,21 @@ PinLayout also has methods to position relative to other views but with also the
451458

452459
**Methods:**
453460

454-
* `above(of relativeViews: UIView..., aligned: HorizontalAlignment)`
455-
Position the view above the specified views and aligned it using the specified HorizontalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: bottomLeft, bottomCenter or bottomRight.
456-
* `below(of relativeViews: UIView..., aligned: HorizontalAlignment)`
457-
Position the view below the specified view and aligned it using the specified HorizontalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topLeft, topCenter or topRight.
458-
* `left(of relativeViews: UIView..., aligned: VerticalAlignment)`
459-
Position the view left of the specified view and aligned it using the specified VerticalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topRight, rightCenter or bottomRight.
460-
* `right(of relativeViews: UIView..., aligned: VerticalAlignment)`
461-
Position the view right of the specified view and aligned it using the specified VerticalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topLeft, leftCenter or bottomLeft.
461+
* `above(of: UIView, aligned: HorizontalAlignment)`
462+
`above(of: [UIView], aligned: HorizontalAlignment)`
463+
Position the view above the specified view(s) and aligned it using the specified HorizontalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: bottomLeft, bottomCenter or bottomRight.
464+
465+
* `below(of: UIView, aligned: HorizontalAlignment)`
466+
`below(of: [UIView], aligned: HorizontalAlignment)`
467+
Position the view below the specified view(s) and aligned it using the specified HorizontalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topLeft, topCenter or topRight.
468+
469+
* `left(of: UIView, aligned: VerticalAlignment)`
470+
`left(of: [UIView], aligned: HorizontalAlignment)`
471+
Position the view left of the specified view(s) and aligned it using the specified VerticalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topRight, rightCenter or bottomRight.
472+
473+
* `right(of: UIView, aligned: VerticalAlignment)`
474+
`right(of: [UIView], aligned: HorizontalAlignment)`
475+
Position the view right of the specified view(s) and aligned it using the specified VerticalAlignment. One or many relative views can be specied. This method is similar to pinning one view’s anchor: topLeft, leftCenter or bottomLeft.
462476

463477
**How alignment is applied:**
464478

@@ -469,7 +483,7 @@ Position the view right of the specified view and aligned it using the specified
469483
* `VerticalAlignment.center`: The view's vCenter edge will be aligned with the average vCenter of all relative views.
470484
* `VerticalAlignment.bottom`: The view's bottom edge will be aligned to the bottom most relative view.
471485

472-
:pushpin: **Multiple relative views**: If for example a call to `below(of:, aligned:) specify multiple relative views, the view will be layouted below *ALL* these views. The alignment will be applied using all relative view
486+
:pushpin: **Multiple relative views**: If for example a call to `below(of: [...], aligned:) specify multiple relative views, the view will be layouted below *ALL* these views. The alignment will be applied using all relative view
473487

474488
:pushpin: These methods **set the position of a view's anchor**: topLeft, topCenter, topRight, leftCenter, .... For example `below(of ..., aligned: .right)` set the view's topRight anchor, `right(of ..., aligned: .center) set the view's centerLeft anchor, ...
475489

@@ -479,7 +493,7 @@ Position the view right of the specified view and aligned it using the specified
479493
###### Usage examples:
480494
```swift
481495
view.pin.above(of: view2, aligned: .left)
482-
view.pin.below(of: view2, view3, view4, aligned: .left)
496+
view.pin.below(of: [view2, view3, view4], aligned: .left)
483497
view.pin.left(of: view2, aligned: .top).right(of: view3, aligned: .bottom)
484498
```
485499

@@ -504,7 +518,7 @@ View A should be left aligned to the UIImageView and right aligned to the UILabe
504518
![](docs/pinlayout-relative-multi.png)
505519

506520
```swift
507-
a.pin.below(of: imageView, label, aligned: .left).right(to: label.edge.right).marginTop(10)
521+
a.pin.below(of: [imageView, label], aligned: .left).right(to: label.edge.right).marginTop(10)
508522
```
509523
This is an equivalent solutions using other methods:
510524

Sources/PinLayout+Filters.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// PinLayout+Filters.swift
3+
// PinLayout
4+
//
5+
// Created by DION, Luc (MTL) on 2017-06-18.
6+
// Copyright © 2017 mcswiftlayyout.mirego.com. All rights reserved.
7+
//
8+
#if os(iOS) || os(tvOS)
9+
import UIKit
10+
11+
// Filter out all hidden views (isHidden is true or alpha is 0)
12+
public func visibles(_ views: [UIView]) -> [UIView] {
13+
return views.filter({ !$0.isHidden && $0.alpha > 0 })
14+
}
15+
16+
#endif

Sources/PinLayout.swift

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,25 @@ public protocol PinLayout {
182182
//
183183
// Layout using relative positioning
184184
//
185-
@discardableResult func above(of relativeViews: UIView...) -> PinLayout
186-
@discardableResult func above(of relativeViews: UIView..., aligned: HorizontalAlignment) -> PinLayout
187-
@discardableResult func below(of relativeViews: UIView...) -> PinLayout
188-
@discardableResult func below(of relativeViews: UIView..., aligned: HorizontalAlignment) -> PinLayout
189-
@discardableResult func left(of relativeViews: UIView...) -> PinLayout
190-
@discardableResult func left(of relativeViews: UIView..., aligned: VerticalAlignment) -> PinLayout
191-
@discardableResult func right(of relativeViews: UIView...) -> PinLayout
192-
@discardableResult func right(of relativeViews: UIView..., aligned: VerticalAlignment) -> PinLayout
185+
@discardableResult func above(of: UIView) -> PinLayout
186+
@discardableResult func above(of: [UIView]) -> PinLayout
187+
@discardableResult func above(of: UIView, aligned: HorizontalAlignment) -> PinLayout
188+
@discardableResult func above(of: [UIView], aligned: HorizontalAlignment) -> PinLayout
189+
190+
@discardableResult func below(of: UIView) -> PinLayout
191+
@discardableResult func below(of: [UIView]) -> PinLayout
192+
@discardableResult func below(of: UIView, aligned: HorizontalAlignment) -> PinLayout
193+
@discardableResult func below(of: [UIView], aligned: HorizontalAlignment) -> PinLayout
194+
195+
@discardableResult func left(of: UIView) -> PinLayout
196+
@discardableResult func left(of: [UIView]) -> PinLayout
197+
@discardableResult func left(of: UIView, aligned: VerticalAlignment) -> PinLayout
198+
@discardableResult func left(of: [UIView], aligned: VerticalAlignment) -> PinLayout
199+
200+
@discardableResult func right(of: UIView) -> PinLayout
201+
@discardableResult func right(of: [UIView]) -> PinLayout
202+
@discardableResult func right(of: UIView, aligned: VerticalAlignment) -> PinLayout
203+
@discardableResult func right(of: [UIView], aligned: VerticalAlignment) -> PinLayout
193204

194205
//
195206
// Width, height and size

0 commit comments

Comments
 (0)