【问题标题】:How to add protocol type as subview如何将协议类型添加为子视图
【发布时间】:2018-03-21 01:19:01
【问题描述】:

于是我写了一个简单的协议:

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

并有一个自定义视图:

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”

编辑: 我正在使用 Swift 2.3!

【问题讨论】:

标签: ios swift swift2 swift-protocols protocol-oriented


【解决方案1】:

将属性messageView的类型改为(UIView & PopupMessageType)!

我是说

class PopUpViewController: UIViewController {

    //code...

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

    }

}

【讨论】:

  • 你的意思不是class XYZMessageView: UIView, PopupMessageType吗? (我已经在我的问题中做到了)
  • @Honey 我认为他的意思与我的回答大致相同。唯一的区别是我在答案中使用了类型别名。
  • @Sweeper,正是 :) 为你 +1
【解决方案2】:

在 Swift 4 中,您可以这样做:

typealias PopupMessageViewType = UIView & PopupMessageType

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

【讨论】:

  • 如果我不是 Swift 4?
  • @Honey 然后你必须创建一个继承自 UIView 并实现 PopupMessageType 的通用基类,并从该基类继承其他所有内容。
  • 基本上使需求成为“特殊”子类,而不是协议。虽然那个特殊的子类符合协议并且也是 UIView 的子类?嗯丑。但我明白了。没有其他简单的选择?
  • @Honey 就我而言,没有。
  • @Honey 我想您可以围绕对象创建一个包装类并提供两个计算属性来访问您需要的属性。
【解决方案3】:

免责声明:我不再拥有 swift 2.3 编译器,因为 swift 4 是 iOS 开发的新常态。以下代码可能需要调整才能在 swift 2.3 中运行


本质上,我们将制作一个 2x1 多路复用器,其中两个输入是同一个对象。输出取决于您将多路复用器设置为选择第一个还是第二个。

// 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”。它们是相同的类实例,但它们被强制转换为不同的类型。

我希望这可以帮助您在 swift 2.3 中到达您想去的地方

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多