Как добавить тип протокола в качестве подпредставления

Итак, я написал простой протокол:

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'

РЕДАКТИРОВАТЬ: я на Swift 2.3!

3 ответа

Решение

Измените тип свойства messageView на (UIView & PopupMessageType)!

Я имею в виду

class PopUpViewController: UIViewController {

    //code...

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

    }

}

В Swift 4 вы можете сделать это:

typealias PopupMessageViewType = UIView & PopupMessageType

А потом использовать PopupMessageViewType как тип переменной.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: у меня больше нет компилятора 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) Я дважды ввожу "inputView" для инициализатора ObjectPopupMessageTypeProtocolMux. Это один и тот же экземпляр класса, но они приводятся к разным типам.

Я надеюсь, что это поможет вам добраться туда, куда вы хотите пойти в быстрой 2,3

Другие вопросы по тегам