-
Notifications
You must be signed in to change notification settings - Fork 527
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
Conversation
This also adds a major refactoring to Cartography, supporting UILayoutGuide and adding a proper support to UILayoutSupport in face of the release of iOS 11.0
Adding support to UILayoutGuide
Also, because I extended the number of |
The breaking change that this PR introduces is that code that today looks like this constrain(view) { view in
view.top == vc.topLayoutGuideCartography
} will change to: constrain(view, vc.car_topLayoutGuide) { view, guide in
view.top == guide.bottom
} This adds more flexibility as you can also now constrain to the top/height attributes of an The whole idea in this PR is to unify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! 👏👏👏
I like LayoutProxy
s splitted into multiple directions, and separating ViewProxy
and LayoutGuideProxy
so that ViewProxy.safeAreaLayoutGuide
/ LayoutGuideProxy.owningView
is possible (I think we need test cases for this).
A bit downside is the use of as!
casts in many places, but I guess it is needed unless we introduce new messy type-erased types.
For terminology, I personally prefer items
over elements
since "item" is used throughout Auto Layout system (e.g. NSLayoutConstraint(item:...)
).
|
||
@available(iOS, introduced: 9.0) | ||
@available(tvOS, introduced: 9.0) | ||
public final class LayoutGuideProxy: SupportsPositioningLayoutProxy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UILayoutGuide
doesn't support firstBaseline
/ lastBaseline
, so this should not conform to SupportsBaselineLayoutProxy
(super protocol).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be patching up that. Thanks @inamiy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, owningView
has been implicitly tested. I think the missing test cases are for safeAreaLayoutGuide
which I'll also add. I'll also rename LayoutElement
to LayoutItem
.
I'll try to figure out something about the IUOs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so this will need a bit of a rebase - I've released #267 as a 2.1.0 release The idea behind this all seems 👍 to me, I'm happy to 3.0 it |
Okay, I merged the current master with my fork. Please check if everything is okay and we can merge and release Cartography 3.0 :) |
Oh yeah, my bad 👍 |
I'll give this a one over |
Ah yeah, can I get an example of how to migrate from 2.x to 3.0? To add to the release notes. Then this is good to go from my side 👍 |
I posted above but: The properties Code that today looks like this: constrain(view) { view in
view.top == self.topLayoutGuideCartography
view.bottom == self.bottomLayoutGuideCartography
} now will look like this: constrain(view, self.car_topLayoutGuide, self.car_bottomLayoutGuide) { view, topLayoutGuide, bottomLayoutGuide in
view.top == topLayoutGuide.bottom
view.bottom == bottomLayoutGuide.top
} |
Cartography/View.swift
Outdated
@@ -14,8 +14,6 @@ import Foundation | |||
|
|||
extension UIView: LayoutItem { | |||
public func asProxy(context: Context) -> ViewProxy { | |||
self.translatesAutoresizingMaskIntoConstraints = false |
There was a problem hiding this comment.
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 😕
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 🙄
@orta I posted the explanation above, please check. |
Ah yeah, thanks, OK, let's get the 3.0 train going |
There is an issue with this if we are adding more than five views we have to use let views:[LayoutItem] = [view1,view2,self.car_topLayoutGuide, self.car_bottomLayoutGuide ] error |
@pprevalon That is why I added more overloads to The reason why this happens is because Swift doesn't allow us to use covariant generics, but instead all are invariant, making the array conversion a problem. e.g. the signature is If anyone has any solution to this problem, or a way to work around it, it'd be nice to hear, but I can't think of a way in Swift to create a working interface for that. |
I'm confused about this change. With #267 we could do |
Never mind, I'm silly, This is actually what I'm doing: if #available(iOS 11.0, *) {
constrain(self.scrollView, self) { scroll, superview in
scroll.edges == superview.safeAreaLayoutGuide.edges
}
} else {
constrain(self.scrollView, self) { scroll, superview in
scroll.edges == superview.edges
}
} This happens to be enough in my case cause this view isn't affected by top or bottom layout guides (it's in the middle of the screen). |
@NachoSoto if you need to use top layout guide and bottom layout guide you could use: constrain(self.scrollView, self.car_topLayouGuide, self.car_bottomLayoutGuide) { scroll, topGuide, bottomGuide in
scroll.top == topGuide.bottom
scroll.bottom == bottomGuide.top
scroll.leading == scroll.superview!.leading
scroll.trailing == scroll.superview!.trailing
} |
This pull-request adds support in Cartography to use
UILayoutGuide
s and improves Cartography to work with iOS 11.0 new features.There's a breaking change regarding
UILayoutSupport
as I made it simpler to constrain elements such assafeAreaLayoutGuide
and general views. This breaking change reflects that you no longer will usetopLayoutGuideCartography
orbottomLayoutGuideCartography
inside theconstrain
block but instead you pass a property of the view controller to the method (e.g. now named bothcar_topLayoutGuide
andcar_bottomLayoutGuide
) so you can attach constraints to itsheight
,top
orbottom
as anchors are specified by the documentation.There's also a convenience property in the new
ViewProxy
that allows you to directly access a brand newLayoutProxy
corresponding to thesafeAreaLayoutGuide
in iOS 11.0 as suggested by @gsampaio .This should be able to close issues #268 and #267, and improve upon #207.
I look forward to suggestions in how to improve this pull request. Thanks.