Closed rlwimi closed 6 years ago
My guess is that it wasn't marked as public
because we didn't see a use case, but yours is definitely intriguing. @jvisenti should make the call, but this seems like a reasonable request to me.
@rlwimi @ZevEisenberg I believe AnchorPair
is essentially an internal
type because exposing the initializer publicly could allow for unsafe usage of the API. Consider this function:
func == <T, U>(lhs: AnchorPair<T, U>, rhs: AnchorPair<T, U>) -> ConstraintPair
If you were to construct two AnchorPair<NSLayoutAnchor, NSLayoutAnchor>
, you could mix NSLayoutXAxisAnchor
and NSLayoutYAxisAnchor
however you wanted, which would result in a crash if you attempted to use this operator on mismatched types, i.e. trying to constraint an XAxisAnchor to a YAxisAnchor. The current API forbids this by construction.
That said, the existence of a valid use case may outweigh the pretty minor risk that comes with it. Happy to take a look at a PR if you have something put together already, and see how it could fit in.
I was just reading through some code that I wrote in a project, and found what I believe is a valid use case:
var safeCenterAnchors: AnchorPair<NSLayoutXAxisAnchor, NSLayoutYAxisAnchor> {
if #available(iOS 11.0, *) {
return AnchorPair(first: safeAreaLayoutGuide.centerXAnchor, second: safeAreaLayoutGuide.centerYAnchor)
}
else {
return centerAnchors
}
}
Thanks, everyone! Much appreciated.
To extend Anchorage in an application-specific way, one might create convenience methods to return an
AnchorPair
, make newAnchorGroupProviding
conformers, or extendAnchorGroupProviding
to specify new groups. These approaches start with being able to construct anAnchorPair
outside of the Anchorage module.I'm not sure this qualifies as the most "practical" example, but here is my real-world use case. I've implemented a vertical columns-based layout system in order to match the way my designer works, to support handling devices with different widths by scaling the UI rather than implementing (and designing) a responsive design or doing nothing.
So for example, I'd like to be express a layout like
That's pretty raw, and you might imagine a convenience method to make this
The
AnchorPair
initializer is markedinternal
, so I can't use it directly. I've hobbled by with a hack of replicating the internal initializer with slightly different parameter labels, intending to bring this very question in front of this group. With Swift 4.1 and SE-0189, this is now explicitly deprecated.What is the reasoning behind disallowing
AnchorPair
construction outside of Anchorage? Is there a downside or complication to making its initializerpublic
that I'm not seeing?Obviously, I have alternatives. I can always use Anchorage as the implementation for layout convenience methods, but integration with the DSL is so much nicer than mixing it with method calls.
I'd love to hear what you think. In the event that there aren't objections – maybe this initializer was just very conservatively marked
internal
– I'll post a PR. In that case, I'd have some organizational questions around theInternal.swift
file.