Swift needs to be able to determine the types at compile-time but you try to return either
NSLayoutAnchor<NSLayoutXAxisAnchor>
or NSLayoutAnchor<NSLayoutYAxisAnchor>
objects depending on
the passed edge
parameter.
What you could do is is split up your edges into edges related to x-axis and y-axis:
extension UIView
{
public enum XLayoutEdge {
case right
// ...
}
public enum YLayoutEdge {
case top
// ...
}
func anchor(for edge: XLayoutEdge) -> NSLayoutAnchor<NSLayoutXAxisAnchor> {
switch edge
{
case .right: return rightAnchor
// ...
}
}
func anchor(for edge: YLayoutEdge) -> NSLayoutAnchor<NSLayoutYAxisAnchor> {
switch edge
{
case .top: return topAnchor
// ...
}
}
public func constrain(edge edge1: XLayoutEdge, to edge2: XLayoutEdge, of view: UIView) -> NSLayoutConstraint {
return anchor(for: edge1).constraint(equalTo: view.anchor(for: edge2))
}
public func constrain(edge edge1: YLayoutEdge, to edge2: YLayoutEdge, of view: UIView) -> NSLayoutConstraint {
return anchor(for: edge1).constraint(equalTo: view.anchor(for: edge2))
}
func useEdges(view: UIView)
{
_ = constrain(edge: .right, to: .right, of: view)
_ = constrain(edge: .top, to: .top, of: view)
}
}
It would get even worse because you would have to consider NSLayoutDimension
, too. You could play around with generics
but you'd probably end up replicating in some way what Apple has already put in place for you :).
That's why I think you are working against the system here. Taking a step back, why not work with anchors directly?
extension UIView
{
func useAnchors(view: UIView)
{
_ = rightAnchor.constraint(equalTo: view.rightAnchor)
_ = topAnchor.constraint(equalTo: view.bottomAnchor)
}
}
If you want to write your own convenience functions you could do it like this:
extension UIView
{
public func constrain<T>(_ anchor1: NSLayoutAnchor<T>, to anchor2: NSLayoutAnchor<T>) -> NSLayoutConstraint {
return anchor1.constraint(equalTo: anchor2)
}
func useYourOwnFunctions(view: UIView)
{
_ = constrain(rightAnchor, to: view.rightAnchor)
_ = constrain(topAnchor, to: view.bottomAnchor)
}
}