2015-09-14 2 views
0

У меня есть вопрос, связанный с дизайном.Как создать массив объектов, которые подтверждают определенный протокол и имеют другой родительский класс?

Существует класс, унаследованный от CAShapeLayer и еще один класс, унаследованный от CATextLayer, и оба из них подтверждают определенный протокол, как показано ниже.

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") 
    } 
} 

Подкласс UIView имеет массив объектов, которые подтверждают этот протокол:

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

То, что я пытаюсь сделать здесь называть прекращение функции() из customLayers и добавить их к ним слой этого пользовательского UIView.

class CustomView: UIView { 

    var customLayers = [HogeProtocol]() 

    func callTheFunctionAndAddSublayer() { 

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

    } 
} 

В этом случае элементы подтверждает протокол, но не может быть добавлена ​​к подслоям, потому что они не наследуется от CALayer. Мне хотелось бы создать массив объектов, унаследованных от CALayer (который является общим родительским классом для CAShapeLayer и CATextLayer) И подтверждение протокола, но быстрый не позволяет мне это делать (насколько я знаю ...)

Кажется очень простой проблемой и догадываться, что может быть решение уже, но я не мог найти ответы после часов исследования Google ... Любые идеи?

+0

В Swift не существует возможности объявить переменную, принадлежащую классу, и одновременно соответствует протоколу. Я отправил отчет об ошибке Apple, и он помечается как дубликат другой ошибки, которая в настоящее время открыта. Для вашего случая я предлагаю хранить в двух отдельных переменных, один для класса, один для протокола. – Pang

+0

См. Также: 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

+0

Ох, спасибо большое! Я сделаю другой способ и надеюсь, что Apple скоро исправит эту функцию ... – hagmas

ответ

0

Вам необходимо опустить объект массива с помощью as? или as! в CALayer.

+0

Спасибо ... Downcasting using if let является самым простым способом сделать это кажется – hagmas

0

Попробуйте это:

for customLayer in customLayers { 
    customLayer.aFunction() 
    layer.addSublayer(customLayer as! CALayer) // would crash if customLayer is not of CALayer 
} 
0

Вы можете преобразовать объект CALayer и проверить, если это действительно своего рода 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) 
      } 
     } 
    } 
} 
Смежные вопросы