2017-10-09 77 views
1

所以我寫了一個簡單的協議:如何添加協議類型爲子視圖

protocol PopupMessageType{ 
    var cancelButton: UIButton {get set} 
    func cancel() 
} 

,並有customView:

class XYZMessageView: UIView, PopupMessageType { 
... 
} 

,然後我目前有:

class PopUpViewController: UIViewController { 

    //code... 

    var messageView : CCPopupMessageView! 
    private func setupUI(){ 
    view.addSubview(messageView) 

    } 

} 

但我想要做的是:

class PopUpViewController: UIViewController { 

    //code... 

    var messageView : PopupMessageType! 
    private func setupUI(){ 
    view.addSubview(messageView) // ERROR 

    } 

} 

的錯誤,我得到:

無法將類型的價值 'PopupMessageType!'預期參數 型 '的UIView'

編輯: 我對雨燕2.3!

+1

如果讓popupView = messageView爲? UIView {view.addSubview(popupView)} else {//處理messageView不是UIView的情況} – Lukas

+0

相關:https://stackoverflow.com/questions/26401778/in-swift-how-can-i-declare -a-variable-of-a-specific-type-that-c​​onforms-to-one-o – dan

+0

Swift 2.3已被棄用且不受任何當前工具支持......爲了您自己的利益,請升級。 – PeejWeej

回答

2

更改屬性的類型messageView(UIView & PopupMessageType)!

我的意思是

class PopUpViewController: UIViewController { 

    //code... 

    var messageView : (UIView & PopupMessageType)! 
    private func setupUI(){ 
    view.addSubview(messageView) // ERROR 

    } 

} 
+0

你的意思是除了class XYZMessageView:UIView,PopupMessageType'嗎?(我已經在我的問題中做過) – Honey

+0

@Honey我認爲他的意思與我的答案大致相同。唯一的區別是我在答案中使用了一個類型別名。 – Sweeper

+0

@Sweeper,正是:) +1你 –

2

在斯威夫特4,你可以這樣做:

typealias PopupMessageViewType = UIView & PopupMessageType 

然後用PopupMessageViewType作爲變量的類型。

+0

,如果我不是斯威夫特4? – Honey

+0

@Honey然後,你必須創建一個通用的基類,它繼承自UIView,並實現PopupMessageType並繼承該基類的所有其他類。 – Sweeper

+0

基本上使這個需求成爲一個'特殊'的子類,而不是一個協議。儘管這個特殊的子類符合協議,並且也是從UIView子類化的?醜陋的。但我明白了。沒有其他簡單的選擇? – Honey

2

免責聲明:我沒有swift 2.3編譯器,因爲swift 4是iOS開發的新常態。下面的代碼可能需要調整,以得到它在SWIFT 2.3


工作從本質上講,我們將作出一個2×1多路複用器,其中兩個輸入都是同一個對象。輸出取決於您是否將多路複用器設置爲選擇第一個還是第二個。

// The given protocol 
protocol PopupMessageType{ 
    var cancelButton: UIButton {get set} 
    func cancel() 
} 

// The object that conforms to that protocol 
class XYZMessageView: UIView, PopupMessageType { 
    var cancelButton: UIButton = UIButton() 
    func cancel() { 
    } 
} 

// The mux that lets you choose the UIView subclass or the PopupMessageType 
struct ObjectPopupMessageTypeProtocolMux<VIEW_TYPE: UIView> { 
    let view: VIEW_TYPE 
    let popupMessage: PopupMessageType 
} 

// A class that holds and instance to the ObjectPopupMessageTypeProtocolMux 
class PopUpViewController: UIViewController { 
    var messageWrapper : ObjectPopupMessageTypeProtocolMux<UIView>! 
    private func setupUI(){ 
     view.addSubview(messageWrapper.view) 
    } 
} 

//... 
let vc = PopUpViewController() // create the view controller 
let inputView = XYZMessageView() // create desired view 

// create the ObjectPopupMessageTypeProtocolMux 
vc.messageWrapper = ObjectPopupMessageTypeProtocolMux(view: inputView, popupMessage: inputView) //<-- 1 

vc.messageWrapper.view // retreive the view 
vc.messageWrapper.popupMessage.cancel() // access the protocol's methods 
vc.messageWrapper.popupMessage.cancelButton // get the button 

1)我爲ObjectPopupMessageTypeProtocolMux的初始化程序輸入兩次「inputView」。它們是同一個類實例,但是它們被轉換爲不同的類型。

我希望這可以幫助你到達你想要快速走向的地方2.3

+0

什麼是「2x1多路複用器」? – Honey

+0

這是一種邏輯門,你有兩個輸入,但有一個輸出。 https://en.m.wikipedia.org/wiki/Multiplexer – DerrickHo328