2015-11-05 1 views
0

Я создал SlidingNavigationController, где я хотел иметь инициализатор, который принимает три параметра. Все три параметра должны быть UIViewControllers, но они должны подтвердить мой SlidingIconProtocol. Так что я написал код, как это (упрощенный вариант):Что не так с моим шаблоном/родовым инициализатором/конструктором Swift?

struct SlidingItem { 
    var bigIconView: UIView 
    var smallIconView: UIView 
} 

protocol SlidingIconProtocol { 
    var slidingItem: SlidingItem { get set } 
} 

class SlidingNavigationController: UIViewController { 

    init<T:UIViewController where T:SlidingIconProtocol>(centralVC: T, leftVC: T, rightVC: T) { 
     super.init(nibName: nil, bundle: nil) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 

class CentralVC: UIViewController, SlidingIconProtocol { 
    var slidingItem = SlidingItem(bigIconView: UIView(), smallIconView: UIView()) 
} 

class LeftVC: UIViewController, SlidingIconProtocol { 
    var slidingItem = SlidingItem(bigIconView: UIView(), smallIconView: UIView()) 
} 

class RightVC: UIViewController, SlidingIconProtocol { 
    var slidingItem = SlidingItem(bigIconView: UIView(), smallIconView: UIView()) 
} 


let myVC = SlidingNavigationController(centralVC: CentralVC(), leftVC: LeftVC(), rightVC: RightVC()) 

Проблема заключается в том, что Swift не удается собрать на последней строке кода с: «Не может вызвать инициализатор для типа„SlidingNavigationController“со списком аргументов типа" (centralVC: CentralVC, leftVC: LeftVC, rightVC: RightVC) '"

Не знаете, почему это не работает, так как даже выполнение Swift/Xcode дает мне возможность использовать этот инициализатор. И все переданные параметры подтверждают SlidingIconProtocol.

Кто-нибудь знает, что не так с кодом и как правильно в Swift достичь того же (возможно ли это вообще)?

ответ

1

Вы не можете использовать шаблон, подобный этому. В коде:

init<T:UIViewController where T:SlidingIconProtocol>(centralVC: T, leftVC: T, rightVC: T) 
{ 
    super.init(nibName: nil, bundle: nil) 
} 

T представляет собой класс, который является подклассом UIViewController и реализует SlidingIconProtocol. Так что, когда вы звоните:

let myVC = SlidingNavigationController(centralVC: CentralVC(), leftVC: LeftVC(), rightVC: RightVC()) 

T предполагается в CentralVC (первый параметр), и метод инициализации будет представлен в виде:

init< CentralVC:UIViewController where CentralVC:SlidingIconProtocol>(centralVC: CentralVC, leftVC: CentralVC, rightVC: CentralVC) 
{ 
    super.init(nibName: nil, bundle: nil) 
} 

Но вы передаете другой объект класса как второй и третий параметр. И это вызовет ошибку. В своем классе следующий код действителен:

let myVC = SlidingNavigationController(centralVC: CentralVC(), leftVC: CentralVC(), rightVC: CentralVC()) 

Поскольку все передаваемые аргументы являются объектом того же класса (CentralVC). Так фиксируя проблему, необходимо реализовать метод init следующим образом:

init<T1:UIViewController, T2:UIViewController, T3:UIViewController where T1:SlidingIconProtocol, T2:SlidingIconProtocol, T3:SlidingIconProtocol>(centralVC: T1, leftVC: T2, rightVC: T3) 
{ 
    super.init(nibName: nil, bundle: nil) 
} 
+0

Спасибо за быстрый ответ и объяснения. Я попробовал ваше решение, и оно работает! –

+0

@MatejUkmar: С удовольствием слышу это :) –