0

I have a design related question.

There is a class inherited from CAShapeLayer and one another class inherited from CATextLayer and both of them confirm to a certain protocol like below.

protocol HogeProtocol {
    func aFunction()
}

class A: CAShapeLayer, HogeProtocol {
    func aFunction() {
        print("I am Class A")
    }
}

class B: CATextLayer, HogeProtocol {
    func aFunction() {
        print("I am Class B")
    }
}

A subclass of UIView has an array of objects that confirm this protocol:

class CustomView: UIView {
    var customLayers = [HogeProtocol]()
    func callTheFunctionAndAddSublayer() {
        // some implementation
    }
}

What I am trying to do here is to call aFunction() of the customLayers and add them to them to the layer of this custom UIView.

class CustomView: UIView {

    var customLayers = [HogeProtocol]()

    func callTheFunctionAndAddSublayer() {

        for customLayer in customLayers {
            customLayer.aFunction() // can call
            layer.addSublayer(customLayer) // cannot call.. 
        }

    }
}

In this case, the elements is confirming protocol but cannot be added to sublayers because they are not inherited from CALayer. I wish I could make an array of an object inherited from CALayer (which is the common parent class for CAShapeLayer and CATextLayer) AND confirming to the protocol but swift doesn't allow me to do so (as far as I know...)

It seems very a simple problem and guess there might be a solution already but I couldn't find any answers after hours of google researching... Any ideas?

hagmas
  • 19
  • 5
  • I don't think it is currently possible in Swift to declare a variable that belongs to a class and conforms to a protocol at the same time. I've submitted a bug report to Apple and it is marked as a duplicate of another bug which is currently Open. For your case, I suggest storing in two separate variables, one for the class, one for the protocol. – Pang Sep 14 '15 at 02:11
  • See also: http://stackoverflow.com/questions/26401778/swift-how-can-i-declare-a-variable-of-a-specific-type-that-conforms-to-one-or-m / http://stackoverflow.com/questions/25214484/how-do-i-declare-a-variable-that-has-a-type-and-implements-a-protocol – Pang Sep 14 '15 at 02:14
  • Ohh thanks a lot! I will take an other way around and hope Apple will fix the feature soon... – hagmas Sep 14 '15 at 02:49

3 Answers3

0

You'll need to downcast the array object with as? or as! to a CALayer.

Joshua Sullivan
  • 1,073
  • 8
  • 12
0

Try this:

for customLayer in customLayers {
    customLayer.aFunction()
    layer.addSublayer(customLayer as! CALayer) // would crash if customLayer is not of CALayer
}
Fujia
  • 1,232
  • 9
  • 14
0

You can cast the object to CALayer and check if it is really a kind of CALayer.

class CustomView: UIView
{
    var customLayers = [CALayer]()

    func callTheFunctionAndAddSublayer()
    {
        for customLayer in customLayers
        {
            customLayer.aFunction() // can call

            if let layer = customLayer as? CALayer where layer.isKindOfClass(CALayer)
            {
                layer.addSublayer(layer) 
            }
        }
    }
}
Jason Nam
  • 2,011
  • 2
  • 13
  • 22