如何添加协议类型为子视图

问题描述:

所以我写了一个简单的协议:如何添加协议类型为子视图

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

更改属性的类型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你 –

在斯威夫特4,你可以这样做:

typealias PopupMessageViewType = UIView & PopupMessageType 

然后用PopupMessageViewType作为变量的类型。

+0

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

+0

@Honey然后,你必须创建一个通用的基类,它继承自UIView,并实现PopupMessageType并继承该基类的所有其他类。 – Sweeper

+0

基本上使这个需求成为一个'特殊'的子类,而不是一个协议。尽管这个特殊的子类符合协议,并且也是从UIView子类化的?丑陋的。但我明白了。没有其他简单的选择? – Honey

免责声明:我没有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