I'm trying to write an extension for UIView to make it easier to set anchors for a view.

The idea was to write a setAnchors method like this:

import UIKit

extension UIView {

    func setAnchors(top: Anchor? = nil,
                    bottom: Anchor? = nil,
                    leading: Anchor? = nil,
                    trailing: Anchor? = nil) {
        translatesAutoresizingMaskIntoConstraints = false
        if let top = top, let anchorType = top.type as? NSLayoutAnchor<NSLayoutYAxisAnchor>, let constant = top.constant {
            let constraint = topAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let bottom = bottom, let anchorType = bottom.type as? NSLayoutAnchor<NSLayoutYAxisAnchor>, let constant = bottom.constant {
            let constraint = bottomAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let leading = leading, let anchorType = leading.type as? NSLayoutAnchor<NSLayoutXAxisAnchor>, let constant = leading.constant {
            let constraint = leadingAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let trailing = trailing, let anchorType = trailing.type as? NSLayoutAnchor<NSLayoutXAxisAnchor>, let constant = trailing.constant {
            let constraint = trailingAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }
    }
}

struct Anchor {
    var type: NSLayoutAnchor<AnyObject>
    var constant: CGFloat? = 0.0
}

which can be called like this:

 topView.setAnchors(top: Anchor(type: view.topAnchor), leading: Anchor(type: view.leadingAnchor), trailing: Anchor(type: view.trailingAnchor))

I am getting this following error:

Cannot convert value of type 'NSLayoutAnchor' to expected argument type 'NSLayoutAnchor'

enter image description here

I know I could give topAnchor as NSLayoutYAxisAnchor and so on, and give constant also as parameter to this method to make this work, but I was wondering if there is a way to make it work with this Anchor struct?

1

There are 1 best solutions below

0
On

You can use Generic.

struct Anchor<T: AnyObject>{
    var type: NSLayoutAnchor<T>
    var constant: CGFloat? = 0.0
}

extension UIView {
    func setAnchors<T: AnyObject>(top: Anchor<T>? = nil,
                    bottom: Anchor<T>? = nil,
                    leading: Anchor<T>? = nil,
                    trailing: Anchor<T>? = nil) {
        translatesAutoresizingMaskIntoConstraints = false
        if let top = top, let anchorType = top.type as? NSLayoutAnchor<NSLayoutYAxisAnchor>, let constant = top.constant {
            let constraint = topAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let bottom = bottom, let anchorType = bottom.type as? NSLayoutAnchor<NSLayoutYAxisAnchor>, let constant = bottom.constant {
            let constraint = bottomAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let leading = leading, let anchorType = leading.type as? NSLayoutAnchor<NSLayoutXAxisAnchor>, let constant = leading.constant {
            let constraint = leadingAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }

        if let trailing = trailing, let anchorType = trailing.type as? NSLayoutAnchor<NSLayoutXAxisAnchor>, let constant = trailing.constant {
            let constraint = trailingAnchor.constraint(equalTo: anchorType, constant: constant)
            constraint.isActive = true
        }
    }
}