Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class AutoAdjustingSizeView: BaseView {
row1Item2.pin.right(of: row1Item1, aligned: .top).bottomRight().margin(0, 2, 2, 2)

row2.pin.below(of: row1, aligned: .left).size(of: row1).marginTop(10)
row2Item1.pin.top().right().bottom().width(150).width(25%).margin(2)
row2Item1.pin.top().bottom().right().width(150).margin(2)
row2Item2.pin.left(of: row2Item1, aligned: .top).left().bottom().margin(0, 2, 2, 2)

row3.pin.below(of: row2, aligned: .left).size(of: row1).marginTop(10)
Expand Down
2 changes: 1 addition & 1 deletion Example/PinLayoutSample/UI/Examples/Intro/IntroView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class IntroView: BaseView {
let containerInsets = safeArea.minInsets(UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10))
contentView.pin.all().margin(containerInsets)

logo.pin.top().left().size(100).aspectRatio().marginTop(10)
logo.pin.top().left().width(100).aspectRatio().marginTop(10)
segmented.pin.after(of: logo, aligned: .top).right().marginLeft(10)
textLabel.pin.below(of: segmented, aligned: .left).width(of: segmented).pinEdges().marginTop(10).sizeToFit(.width)
separatorView.pin.below(of: [logo, textLabel], aligned: .left).right(to: segmented.edge.right).marginTop(10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ @implementation IntroObjectiveCView {

- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
Pin.logMissingLayoutCalls = true;

topLayoutGuide = 0;
self.backgroundColor = UIColor.whiteColor;

Expand All @@ -56,6 +58,10 @@ - (id)initWithFrame:(CGRect)frame {
return self;
}

- (void)dealloc {
Pin.logMissingLayoutCalls = false;
}

- (void) layoutSubviews {
[super layoutSubviews];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class IntroRTLView: BaseView {
let containerInsets = safeArea.minInsets(UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10))
contentView.pin.all().margin(containerInsets)

logo.pin.top().start().size(100).aspectRatio().marginTop(10)
logo.pin.top().start().width(100).aspectRatio().marginTop(10)
segmented.pin.after(of: logo, aligned: .top).end().marginStart(10)
textLabel.pin.below(of: segmented, aligned: .start).width(of: segmented).pinEdges().marginTop(10).sizeToFit(.width)
separatorView.pin.below(of: [logo, textLabel], aligned: .start).end(to: segmented.edge.end).marginTop(10)
Expand Down
22 changes: 15 additions & 7 deletions PinLayout.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
242723731F008BF7006A5C3A /* MinMaxWidthHeightSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 242723711F008B85006A5C3A /* MinMaxWidthHeightSpec.swift */; };
242E8DC31EED5AB2005935FB /* RelativePositionMultipleViewsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 242E8DC11EED5982005935FB /* RelativePositionMultipleViewsSpec.swift */; };
243B12BC1FC393580072A9C3 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243C620E1FC3834B0082C327 /* Percent.swift */; };
243B12C81FC3D06F0072A9C3 /* LayoutMethodSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 243B12C41FC3CFC10072A9C3 /* LayoutMethodSpec.swift */; };
243B12CB1FC469D00072A9C3 /* ObjectiveCSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 243B12C91FC469550072A9C3 /* ObjectiveCSpec.m */; };
243C62041FC37F680082C327 /* PinLayoutImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C61FC37C1C0054CADD /* PinLayoutImpl.swift */; };
243C62051FC37F6C0082C327 /* PinLayoutImpl+Coordinates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C71FC37C1C0054CADD /* PinLayoutImpl+Coordinates.swift */; };
243C62061FC37F6C0082C327 /* PinLayoutImpl+Layouting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2475B6C41FC37A900054CADD /* PinLayoutImpl+Layouting.swift */; };
Expand Down Expand Up @@ -50,8 +52,8 @@
24BBE6351F50FA1D0091D5E9 /* UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24BBE6341F50FA1D0091D5E9 /* UnitTests.swift */; };
24BBE6381F52EC380091D5E9 /* UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24BBE6341F50FA1D0091D5E9 /* UnitTests.swift */; };
24D18D171F3B4381008129EF /* RTLSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D151F3B42E0008129EF /* RTLSpec.swift */; };
24D18D241F3E37DD008129EF /* PinLayoutGlobals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* PinLayoutGlobals.swift */; };
24D18D261F3E5EA5008129EF /* PinLayoutGlobals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* PinLayoutGlobals.swift */; };
24D18D241F3E37DD008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; };
24D18D261F3E5EA5008129EF /* Pin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D18D231F3E37DD008129EF /* Pin.swift */; };
CA6C7C85508320B18B1FC777 /* Pods_PinLayoutTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45CE7ABE76F48416DE57DF55 /* Pods_PinLayoutTests.framework */; };
DF7A36BD1E918301000F9856 /* PinEdgesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF7A36BC1E918301000F9856 /* PinEdgesSpec.swift */; };
DFC97CA71E8A8F2C001545D5 /* PinLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */; };
Expand Down Expand Up @@ -86,6 +88,8 @@
241A277C1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinLayoutObjCImpl.swift; sourceTree = "<group>"; };
242723711F008B85006A5C3A /* MinMaxWidthHeightSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinMaxWidthHeightSpec.swift; sourceTree = "<group>"; };
242E8DC11EED5982005935FB /* RelativePositionMultipleViewsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelativePositionMultipleViewsSpec.swift; sourceTree = "<group>"; };
243B12C41FC3CFC10072A9C3 /* LayoutMethodSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutMethodSpec.swift; sourceTree = "<group>"; };
243B12C91FC469550072A9C3 /* ObjectiveCSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObjectiveCSpec.m; sourceTree = "<group>"; };
243C620E1FC3834B0082C327 /* Percent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Percent.swift; path = Impl/Percent.swift; sourceTree = "<group>"; };
244C6E141E776A0C0074FC74 /* MarginsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarginsSpec.swift; sourceTree = "<group>"; };
244DF2F81EF46C500090508B /* PinLayoutTVOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PinLayoutTVOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -116,7 +120,7 @@
249EFE8A1E64FB4C00165E39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
24BBE6341F50FA1D0091D5E9 /* UnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UnitTests.swift; path = Impl/UnitTests.swift; sourceTree = "<group>"; };
24D18D151F3B42E0008129EF /* RTLSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTLSpec.swift; sourceTree = "<group>"; };
24D18D231F3E37DD008129EF /* PinLayoutGlobals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinLayoutGlobals.swift; sourceTree = "<group>"; };
24D18D231F3E37DD008129EF /* Pin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pin.swift; sourceTree = "<group>"; };
45CE7ABE76F48416DE57DF55 /* Pods_PinLayoutTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PinLayoutTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
561BC8B0591ACB691B563927 /* Pods-PinLayoutTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests/Pods-PinLayoutTests.release.xcconfig"; sourceTree = "<group>"; };
6070E55EDEAA3DC58C0B4CDD /* Pods-PinLayoutTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PinLayoutTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PinLayoutTests/Pods-PinLayoutTests.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -205,7 +209,7 @@
children = (
DFC97CA61E8A8F2C001545D5 /* PinLayout.swift */,
24949A2D1EF69474003643D3 /* PinLayout+Filters.swift */,
24D18D231F3E37DD008129EF /* PinLayoutGlobals.swift */,
24D18D231F3E37DD008129EF /* Pin.swift */,
DFA06B031E8B38B300B6D5E7 /* Impl */,
241A277A1F8E958F00B1AD39 /* ObjectiveC */,
2475B6D51FC37D270054CADD /* SupportingFiles */,
Expand All @@ -221,8 +225,10 @@
2469C4FF1E75D74000073BEE /* AdjustSizeSpec.swift */,
248E4C721F7A83FA00C0E7F7 /* AspectRatioTests.swift */,
240F88BC1F0C042500280FC8 /* JustifyAlignSpec.swift */,
243B12C41FC3CFC10072A9C3 /* LayoutMethodSpec.swift */,
244C6E141E776A0C0074FC74 /* MarginsSpec.swift */,
242723711F008B85006A5C3A /* MinMaxWidthHeightSpec.swift */,
243B12C91FC469550072A9C3 /* ObjectiveCSpec.m */,
249EFE881E64FB4C00165E39 /* PinLayoutTests.swift */,
DF7A36BC1E918301000F9856 /* PinEdgesSpec.swift */,
2469C4FB1E74855D00073BEE /* PinEdgeCoordinateSpec.swift */,
Expand Down Expand Up @@ -359,7 +365,7 @@
};
249EFE791E64FB4C00165E39 = {
CreatedOnToolsVersion = 8.2.1;
LastSwiftMigration = 0820;
LastSwiftMigration = 0910;
ProvisioningStyle = Automatic;
};
249EFE821E64FB4C00165E39 = {
Expand Down Expand Up @@ -467,7 +473,7 @@
buildActionMask = 2147483647;
files = (
243C62081FC37F6C0082C327 /* PinLayoutImpl+Warning.swift in Sources */,
24D18D261F3E5EA5008129EF /* PinLayoutGlobals.swift in Sources */,
24D18D261F3E5EA5008129EF /* Pin.swift in Sources */,
243C62041FC37F680082C327 /* PinLayoutImpl.swift in Sources */,
243C62071FC37F6C0082C327 /* PinLayoutImpl+Relative.swift in Sources */,
243B12BC1FC393580072A9C3 /* Percent.swift in Sources */,
Expand All @@ -486,7 +492,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
24D18D241F3E37DD008129EF /* PinLayoutGlobals.swift in Sources */,
24D18D241F3E37DD008129EF /* Pin.swift in Sources */,
2475B6CA1FC37C1C0054CADD /* PinLayoutImpl.swift in Sources */,
241A277E1F8E958F00B1AD39 /* PinLayoutObjCImpl.swift in Sources */,
243C620F1FC3834B0082C327 /* Percent.swift in Sources */,
Expand All @@ -510,7 +516,9 @@
files = (
240F88BE1F0C066800280FC8 /* JustifyAlignSpec.swift in Sources */,
2469C5001E75D74000073BEE /* AdjustSizeSpec.swift in Sources */,
243B12C81FC3D06F0072A9C3 /* LayoutMethodSpec.swift in Sources */,
2482908C1E78CFFC00667D08 /* RelativePositionSpec.swift in Sources */,
243B12CB1FC469D00072A9C3 /* ObjectiveCSpec.m in Sources */,
248E4C741F7A883800C0E7F7 /* AspectRatioTests.swift in Sources */,
240F88C11F0C1F5000280FC8 /* WarningSpec.swift in Sources */,
242E8DC31EED5AB2005935FB /* RelativePositionMultipleViewsSpec.swift in Sources */,
Expand Down
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ Extremely Fast views layouting without auto layout. No magic, pure code, full co
* [Warnings](#warnings)
* [More examples](#more_examples)
* [Examples App](#examples_app)
* [Using PinLayout with Objective-C](#objective_c_interface)
* [PinLayout in Xcode Playgrounds](#playgrounds)
* [PinLayout using Objective-C](#objective_c_interface)
* [Installation](#installation)
* [FAQ](#faq)
* [Comments, ideas, suggestions, issues, ....](#comments)
Expand Down Expand Up @@ -81,7 +82,7 @@ This example layout an image, a UISegmentedControl, a label and a line separator
override func layoutSubviews() {
super.layoutSubviews()

logo.pin.top().left().size(100).aspectRatio().margin(10)
logo.pin.top().left().width(100).aspectRatio().margin(10)
segmented.pin.after(of: logo, aligned: .top).right().marginHorizontal(10)
textLabel.pin.below(of: segmented, aligned: .left).right().marginTop(10).marginRight(10).sizeToFit(.width)
separatorView.pin.below(of: [logo, textLabel], aligned: .left).right(to: segmented.edge.right).marginTop(10)
Expand Down Expand Up @@ -1179,6 +1180,10 @@ Example:
`view.pin.left().width(250).justify(.center)`
👉 PinLayout Warning: justify(center) won't be applied, the left and right coordinates must be set to justify the view.

* Layout must be executed from the **Main thread**.
👉 PinLayout Warning: Layout must be executed from the Main Thread!


### Disabling warnings

Warnings can be disabled also in debug mode by setting the boolean Pin.logWarnings to false.
Expand Down Expand Up @@ -1335,10 +1340,18 @@ This app is available in the `Example` folder. Note that you must do a `pod inst

<br>

## Using PinLayout with Objective-C <a name="objective_c_interface"></a>
## PinLayout in Xcode Playgrounds <a name="playgrounds"></a>

PinLayout layouts views immediately after the line containing `.pin` has been fully executed, thanks to ARC (Automatic Reference Counting) this works perfectly on iOS/tvOS/macOS simulators and devices. But in Xcode Playgrounds, ARC doesn't work as expected, object references are kept much longer. This is a well documented issue and have a little impact on the PinLayout behaviour.

[See here for more details about using PinLayout in Xcode playgrounds](docs/xcode_playground.md)

<br>

## PinLayout using Objective-C <a name="objective_c_interface"></a>
PinLayout also expose an Objective-C interface slightly different than the Swift interface.

[See here for more details](docs/objective_c.md).
[See here for more details](docs/objective_c.md)

<br>

Expand Down
20 changes: 15 additions & 5 deletions Sources/Impl/PinLayoutImpl+Warning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,35 @@ extension PinLayoutImpl {

internal func warnPropertyAlreadySet(_ propertyName: String, propertyValue: CGFloat, _ context: Context) {
guard Pin.logWarnings else { return }
displayWarning("PinLayout Conflict: \(context()) won't be applied since it value has already been set to \(propertyValue).")
displayWarning("PinLayout Conflict: \(context()) won't be applied since it value has already been set to \(propertyValue.description).")
}

internal func warnPropertyAlreadySet(_ propertyName: String, propertyValue: CGSize, _ context: Context) {
guard Pin.logWarnings else { return }
displayWarning("PinLayout Conflict: \(context()) won't be applied since it value has already been set to CGSize(width: \(propertyValue.width), height: \(propertyValue.height)).")
displayWarning("PinLayout Conflict: \(context()) won't be applied since it value has already been set to CGSize(width: \(propertyValue.width.description), height: \(propertyValue.height.description)).")
}

internal func warnConflict(_ context: Context, _ properties: [String: Any]) {
guard Pin.logWarnings else { return }
var warning = "PinLayout Conflict: \(context()) won't be applied since it conflicts with the following already set properties:"
properties.forEach { (property) in
warning += "\n \(property.key): \(property.value)"
warning += "\n \(property.key): "

if let floatValue = property.value as? CGFloat {
warning += "\(floatValue.description)"
} else {
warning += "\(property.value)"
}
}

displayWarning(warning)
}

internal func displayLayoutWarnings() {
if !Thread.isMainThread {
warn("Layout must be executed from the Main Thread!")
}

if let justify = justify {
func context() -> String { return "justify(.\(justify.description))" }
if !((_left != nil && _right != nil) || (shouldPinEdges && width != nil && (_left != nil || _right != nil || _hCenter != nil))) {
Expand All @@ -96,7 +106,7 @@ extension PinLayoutImpl {

internal func displayWarning(_ text: String) {
var displayText = "\n👉 \(text)"
displayText += "\n (Layouted view info: Type: \(viewName(view)), Frame: \(view.frame)"
displayText += "\n(Layouted view info: Type: \(viewName(view)), Frame: \(view.frame)"

var currentView = view
var hierarchy: [String] = []
Expand All @@ -111,7 +121,7 @@ extension PinLayoutImpl {
displayText += ", Tag: \(view.tag))\n"

print(displayText)
_pinlayoutUnitTestLastWarning = text
Pin.lastWarningText = text
}

internal func viewDescription(_ view: UIView) -> String {
Expand Down
Loading