Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support to UILayoutGuide #269

Merged
merged 20 commits into from
Oct 31, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2732065
Adding support to UILayoutGuide in Cartography
corujautx Oct 11, 2017
462273b
Removing elements from constrain method signature
corujautx Oct 16, 2017
6bcf956
Adding tests for LayoutGuide support
corujautx Oct 16, 2017
6421a8c
Adding convenience support to safeAreaLayoutGuide
corujautx Oct 16, 2017
6729905
Fixing documentation replacing references to view
corujautx Oct 16, 2017
a91c01a
Merge pull request #1 from corujautx/feature/layout-guide-support
corujautx Oct 16, 2017
b6eb9c9
Changing access control of proxy properties
corujautx Oct 16, 2017
e48af31
Fixing issues with macOS
corujautx Oct 16, 2017
bcf9c93
Fixing issue with top margin
corujautx Oct 16, 2017
a31a7e2
Removing baseline properties from layout guide proxy
corujautx Oct 17, 2017
878f609
Removing IUOs & adding type-erasure
corujautx Oct 17, 2017
1bb14b9
Adding safeAreaLayoutGuide tests
corujautx Oct 17, 2017
e4585a3
Renaming `LayoutElement` to `LayoutItem`
corujautx Oct 17, 2017
f2a8b73
Fixing type-erasures not being linked for the macOS target
corujautx Oct 17, 2017
767821e
Merge branch 'master' of https://github.com/robb/Cartography
corujautx Oct 18, 2017
5cd25b2
Fixing autoresizing mask to match older behavior
corujautx Oct 24, 2017
4cdc8fa
Fixing generation of view proxies
corujautx Oct 24, 2017
143d9fc
Fixing issue with Context not disabling autoresizing mask translation
corujautx Oct 24, 2017
da5e483
Changing podspec version to 3.0.0
corujautx Oct 24, 2017
fc476fe
Adding AutoresizingMaskLayoutProxy to macOS and tvOS targets
corujautx Oct 24, 2017
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
2 changes: 1 addition & 1 deletion Cartography.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "Cartography"
s.version = "2.0.0"
s.version = "3.0.0"
s.summary = "Declarative Auto Layout in Swift"

s.description = <<-DESC
Expand Down
4 changes: 4 additions & 0 deletions Cartography.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
9722953D1F950A1F00FA4AF9 /* ViewProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97E7F0A81F8D598A004857CE /* ViewProxy.swift */; };
9722953E1F950A2E00FA4AF9 /* LayoutSupportProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17C8F1F8E73F200C57CE1 /* LayoutSupportProxy.swift */; };
9722953F1F950A3000FA4AF9 /* LayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AF7EED1CABEABC00249E27 /* LayoutSupport.swift */; };
977C36821F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */; };
979558E41F9700B40096BBEA /* LayoutGuideSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 979F29C91F94DC6B00257363 /* LayoutGuideSpec.swift */; };
979558EC1F97015E0096BBEA /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17C9E1F8E774700C57CE1 /* TestView.swift */; };
979558ED1F97015E0096BBEA /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D17C9E1F8E774700C57CE1 /* TestView.swift */; };
Expand Down Expand Up @@ -244,6 +245,7 @@
7BBFE24E2FED786C571966AE /* Pods_Cartography_Mac_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Cartography_Mac_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7D3596ED3F137EB677E57692 /* Pods-TestPods-Cartography-tvOS-tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestPods-Cartography-tvOS-tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-TestPods-Cartography-tvOS-tests/Pods-TestPods-Cartography-tvOS-tests.release.xcconfig"; sourceTree = "<group>"; };
825625A8CCFA9B2B102BDDDB /* Pods_TestPods_Cartography_Mac_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TestPods_Cartography_Mac_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoresizingMaskLayoutProxy.swift; sourceTree = "<group>"; };
979F29C91F94DC6B00257363 /* LayoutGuideSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutGuideSpec.swift; sourceTree = "<group>"; };
97D17C8F1F8E73F200C57CE1 /* LayoutSupportProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutSupportProxy.swift; sourceTree = "<group>"; };
97D17C951F8E774400C57CE1 /* LayoutGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutGuide.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -429,6 +431,7 @@
97D17CA91F8E779300C57CE1 /* LayoutGuideProxy.swift */,
97D17C991F8E774700C57CE1 /* CartographyTests */,
54C96A14195063CD000CDD27 /* Supporting Files */,
977C36811F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift */,
);
path = Cartography;
sourceTree = "<group>";
Expand Down Expand Up @@ -904,6 +907,7 @@
547BC85519E2DD06007BEE9E /* Context.swift in Sources */,
97F50E521F962CF300C6DCF5 /* LayoutProxy+TypeErasure.swift in Sources */,
EE8531501F936462003EC021 /* LayoutItem.swift in Sources */,
977C36821F9FAC890057A057 /* AutoresizingMaskLayoutProxy.swift in Sources */,
545F858D195322EA00791F75 /* Edges.swift in Sources */,
97E7F0A91F8D598A004857CE /* ViewProxy.swift in Sources */,
546E9E8D1950A31100B16707 /* Dimension.swift in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions Cartography/Align.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ import AppKit

private func makeEqual<P: RelativeEquality, T: LayoutProxy>(by attribute: (T) -> P, items: [T]) -> [NSLayoutConstraint] {
if let first = items.first {
if let first = first as? AutoresizingMaskLayoutProxy {
first.translatesAutoresizingMaskIntoConstraints = false
}

let rest = items.dropFirst()

return rest.reduce([]) { acc, current in
if let current = current as? AutoresizingMaskLayoutProxy {
current.translatesAutoresizingMaskIntoConstraints = false
}

return acc + [ attribute(first) == attribute(current) ]
}
} else {
Expand Down
13 changes: 13 additions & 0 deletions Cartography/AutoresizingMaskLayoutProxy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// AutoresizingMaskLayoutProxy.swift
// Cartography-iOS
//
// Created by Vitor Travain on 24/10/17.
// Copyright © 2017 Robert Böhnke. All rights reserved.
//

import Foundation

public protocol AutoresizingMaskLayoutProxy: LayoutProxy {
var translatesAutoresizingMaskIntoConstraints: Bool { get set }
}
4 changes: 4 additions & 0 deletions Cartography/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public class Context {
internal var constraints: [Constraint] = []

internal func addConstraint(_ from: Property, to: Property? = nil, coefficients: Coefficients = Coefficients(), relation: LayoutRelation = .equal) -> NSLayoutConstraint {
if let fromItem = from.item as? View {
fromItem.translatesAutoresizingMaskIntoConstraints = false
}

let layoutConstraint = NSLayoutConstraint(item: from.item,
attribute: from.attribute,
relatedBy: relation,
Expand Down
4 changes: 4 additions & 0 deletions Cartography/Distribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#endif

@discardableResult private func reduce<T: LayoutProxy>(_ items: [T], combine: (T, T) -> NSLayoutConstraint) -> [NSLayoutConstraint] {
if let last = items.last as? AutoresizingMaskLayoutProxy {
last.translatesAutoresizingMaskIntoConstraints = false
}

if let first = items.first {
let rest = items.dropFirst()

Expand Down
6 changes: 1 addition & 5 deletions Cartography/LayoutGuideProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ public final class LayoutGuideProxy: SupportsPositioningLayoutProxy {
}

public var owningView: ViewProxy? {
guard let owningView = layoutGuide.owningView else {
return nil
}

return ViewProxy(context: context, view: owningView)
return layoutGuide.owningView?.asProxy(context: context)
}
}
#endif
24 changes: 12 additions & 12 deletions Cartography/LayoutProxy+TypeErasure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

struct AnyTopLayoutProxy: SupportsTopLayoutProxy {
final class AnyTopLayoutProxy: SupportsTopLayoutProxy {
let proxy: SupportsTopLayoutProxy

var context: Context {
Expand All @@ -24,7 +24,7 @@ struct AnyTopLayoutProxy: SupportsTopLayoutProxy {
}
}

struct AnyBottomLayoutProxy: SupportsBottomLayoutProxy {
final class AnyBottomLayoutProxy: SupportsBottomLayoutProxy {
let proxy: SupportsBottomLayoutProxy

var context: Context {
Expand All @@ -40,7 +40,7 @@ struct AnyBottomLayoutProxy: SupportsBottomLayoutProxy {
}
}

struct AnyLeftLayoutProxy: SupportsLeftLayoutProxy {
final class AnyLeftLayoutProxy: SupportsLeftLayoutProxy {
let proxy: SupportsLeftLayoutProxy

var context: Context {
Expand All @@ -56,7 +56,7 @@ struct AnyLeftLayoutProxy: SupportsLeftLayoutProxy {
}
}

struct AnyRightLayoutProxy: SupportsRightLayoutProxy {
final class AnyRightLayoutProxy: SupportsRightLayoutProxy {
let proxy: SupportsRightLayoutProxy

var context: Context {
Expand All @@ -72,7 +72,7 @@ struct AnyRightLayoutProxy: SupportsRightLayoutProxy {
}
}

struct AnyLeadingLayoutProxy: SupportsLeadingLayoutProxy {
final class AnyLeadingLayoutProxy: SupportsLeadingLayoutProxy {
let proxy: SupportsLeadingLayoutProxy

var context: Context {
Expand All @@ -88,7 +88,7 @@ struct AnyLeadingLayoutProxy: SupportsLeadingLayoutProxy {
}
}

struct AnyTrailingLayoutProxy: SupportsTrailingLayoutProxy {
final class AnyTrailingLayoutProxy: SupportsTrailingLayoutProxy {
let proxy: SupportsTrailingLayoutProxy

var context: Context {
Expand All @@ -104,7 +104,7 @@ struct AnyTrailingLayoutProxy: SupportsTrailingLayoutProxy {
}
}

struct AnyCenterXLayoutProxy: SupportsCenterXLayoutProxy {
final class AnyCenterXLayoutProxy: SupportsCenterXLayoutProxy {
let proxy: SupportsCenterXLayoutProxy

var context: Context {
Expand All @@ -120,7 +120,7 @@ struct AnyCenterXLayoutProxy: SupportsCenterXLayoutProxy {
}
}

struct AnyCenterYLayoutProxy: SupportsCenterYLayoutProxy {
final class AnyCenterYLayoutProxy: SupportsCenterYLayoutProxy {
let proxy: SupportsCenterYLayoutProxy

var context: Context {
Expand All @@ -136,7 +136,7 @@ struct AnyCenterYLayoutProxy: SupportsCenterYLayoutProxy {
}
}

struct AnyBaselineLayoutProxy: SupportsBaselineLayoutProxy {
final class AnyBaselineLayoutProxy: SupportsBaselineLayoutProxy {
let proxy: SupportsBaselineLayoutProxy

var context: Context {
Expand All @@ -152,7 +152,7 @@ struct AnyBaselineLayoutProxy: SupportsBaselineLayoutProxy {
}
}

struct AnyHorizontalDistributionLayoutProxy: SupportsLeadingLayoutProxy, SupportsTrailingLayoutProxy {
final class AnyHorizontalDistributionLayoutProxy: SupportsLeadingLayoutProxy, SupportsTrailingLayoutProxy {
let proxy: SupportsLeadingLayoutProxy & SupportsTrailingLayoutProxy

var context: Context {
Expand All @@ -168,7 +168,7 @@ struct AnyHorizontalDistributionLayoutProxy: SupportsLeadingLayoutProxy, Support
}
}

struct AnyLeftToRightDistributionLayoutProxy: SupportsLeftLayoutProxy, SupportsRightLayoutProxy {
final class AnyLeftToRightDistributionLayoutProxy: SupportsLeftLayoutProxy, SupportsRightLayoutProxy {
let proxy: SupportsLeftLayoutProxy & SupportsRightLayoutProxy

var context: Context {
Expand All @@ -184,7 +184,7 @@ struct AnyLeftToRightDistributionLayoutProxy: SupportsLeftLayoutProxy, SupportsR
}
}

struct AnyVerticalDistributionLayoutProxy: SupportsTopLayoutProxy, SupportsBottomLayoutProxy {
final class AnyVerticalDistributionLayoutProxy: SupportsTopLayoutProxy, SupportsBottomLayoutProxy {
let proxy: SupportsTopLayoutProxy & SupportsBottomLayoutProxy

var context: Context {
Expand Down
2 changes: 1 addition & 1 deletion Cartography/LayoutProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

public protocol LayoutProxy {
public protocol LayoutProxy: class {
var context: Context { get }
var item: AnyObject { get } //type-erased Layoutitem
}
Expand Down
4 changes: 0 additions & 4 deletions Cartography/View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import Foundation

extension UIView: LayoutItem {
public func asProxy(context: Context) -> ViewProxy {
self.translatesAutoresizingMaskIntoConstraints = false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 767821e...da5e483, why did translatesAutoresizingMaskIntoConstraints = false move to other methods?
It seems scattered than before 😕

Copy link
Contributor Author

@corujautx corujautx Oct 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sorry about that.

Here's the problem tho: this introduces a bug/breaking change on the library depending on how people use it, and I kinda discovered that by pointing out my fork to a project we are developing at our company.

When I centralized the translatesAutoresizingMaskIntoConstraints in the proxy generation step I was thinking "Hey this is going to make the library a lot more simple", but the issue is that lot of people use the syntax as in:

constrain(view, superview) { view, superview in ... }

instead of:

constrain(view) { view in 
    view.top == view.superview!.top
}

in order to avoid IUOs

When we moved to the proxy code, the first case generated a side effect of setting up translatesAutoresizingMaskIntoConstraints in the superview, and this broke the layout of several root views in UINavigationController or any container view controller.

I couldn't predict this side effect being generated by the code I made, so I changed back into the original behavior of the library, even if it looks ugly, to avoid more breaking changes.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explanation!
So, translatesAutoresizingMaskIntoConstraints = false impl is actually back to the original code now 🙄


return ViewProxy(context: context, view: self)
}
}
Expand All @@ -25,8 +23,6 @@ import Foundation

extension NSView: LayoutItem {
public func asProxy(context: Context) -> ViewProxy {
self.translatesAutoresizingMaskIntoConstraints = false

return ViewProxy(context: context, view: self)
}
}
Expand Down
21 changes: 12 additions & 9 deletions Cartography/ViewProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,37 @@
// Copyright © 2017 Robert Böhnke. All rights reserved.
//

public final class ViewProxy: SupportsPositioningLayoutProxy, SupportsBaselineLayoutProxy {
public final class ViewProxy: SupportsPositioningLayoutProxy, SupportsBaselineLayoutProxy, AutoresizingMaskLayoutProxy {
public var context: Context

private let view: View
public var item: AnyObject {
return self.view
}

public var translatesAutoresizingMaskIntoConstraints: Bool {
get {
return view.translatesAutoresizingMaskIntoConstraints
}
set(value) {
view.translatesAutoresizingMaskIntoConstraints = value
}
}

public init(context: Context, view: View) {
self.context = context
self.view = view
}

public var superview: ViewProxy? {
guard let superview = self.view.superview else {
return nil
}

return ViewProxy(context: context, view: superview)
return view.superview?.asProxy(context: context)
}

#if os(iOS) || os(tvOS)
@available(iOS, introduced: 11.0)
@available(tvOS, introduced: 11.0)
public var safeAreaLayoutGuide: LayoutGuideProxy {
let layoutGuide = view.safeAreaLayoutGuide

return LayoutGuideProxy(context: context, item: layoutGuide)
return view.safeAreaLayoutGuide.asProxy(context: context)
}
#endif
}