Создание подкласса CIFilter в Swift

Я пытаюсь создать подкласс CIFilter следующим образом:

class ColorMonochromeFilter: CIFilter {

    required init(red: CGFloat!, green: CGFloat!, blue: CGFloat!) {

        super.init(name: "ColorMonochrome")
        setDefaults()

        let colour = UIColor(red: red, green: green, blue: blue, alpha: 1.0)
        setValue(colour, forKey: kCIInputColorKey)
    }
}

Я получаю следующие сообщения об ошибках:

  1. Класс ColorMonochromeFilter не реализует обязательные члены своего суперкласса.
  2. Должен вызвать назначенный инициализатор суперкласса CIFilter.

Похоже, что назначенным инициализатором является init(coder aDecoder: NSCoder!) из-за того, что CIFilter соответствует протоколу NSCoding, а не init(name: String!), который объявлен в расширении CIFilter.

Я могу удалить первую ошибку, добавив:

    required init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
    }

(хотя это кажется немного лишним!)

Есть ли способ решить вторую проблему?


То, что я пытаюсь достичь здесь, является эквивалентом Swift:

@implementation ASHColorMonochromeFilter

    + (ASHColorMonochromeFilter *) filterWithRed: (CGFloat) red green:(CGFloat)green blue:(CGFloat)blue
    {
        ASHColorMonochromeFilter * filter = (ASHColorMonochromeFilter *)[ASHColorMonochromeFilter filterWithName: @"CIColorMonochrome"];

        UIColor * color = [UIColor colorWithRed: red green: green blue: blue alpha: 1.0];
        [filter setValue: color forKey: kCIImageColorSpace];

        return filter;
    }

person Ashley Mills    schedule 29.08.2014    source источник
comment
Вы действительно хотите создать подкласс CIFilter, чтобы добавить/переопределить методы, или вам просто нужен дополнительный инициализатор?   -  person Martin R    schedule 29.08.2014
comment
Что ж, в таком случае я хотел бы понять, как добиться вышеизложенного, если это возможно, или если в моих знаниях есть пробел.   -  person Ashley Mills    schedule 29.08.2014
comment
Я на самом деле не эксперт в этой области, но, насколько я понимаю, init(name: "ColorMonochrome") загружает предопределенный фильтр, поэтому создание подклассов может не иметь смысла. В подклассе вы просто вызовете super.init(). - Если вам просто нужен дополнительный инициализатор для фильтра ColorMonochrome, вы можете определить расширение. (Я подготовил ответ с примером, но я не уверен, что это то, что вам нужно.)   -  person Martin R    schedule 29.08.2014
comment
Я обновил свой вопрос, чтобы попытаться уточнить   -  person Ashley Mills    schedule 30.08.2014


Ответы (1)


Ваш метод класса Objective-C

+ (ASHColorMonochromeFilter *) filterWithRed: (CGFloat) red green:(CGFloat)green blue:(CGFloat)blue

фактически возвращает экземпляр (подкласса) CIFilter. То же самое можно сделать в Swift с помощью удобного инициализатора.

extension CIFilter {
     convenience init(red: CGFloat, green: CGFloat, blue: CGFloat) {
        self.init(name:"CIColorMonochrome")
        setDefaults()
        let colour = UIColor(red: red, green: green, blue: blue, alpha: 1.0)
        setValue(colour, forKey: kCIInputColorKey)
    }
}

который называется как

let filter = CIFilter(red: 0.1, green: 0.2, blue: 0.3)
person Martin R    schedule 29.08.2014
comment
Хорошо, но что произойдет, если я действительно действительно захочу вернуть подкласс? С дополнительными свойствами, скажем? Кажется, что в Swift это намного сложнее, чем в Objective-C в данном случае… или я что-то упускаю? - person Ashley Mills; 30.08.2014
comment
@AshleyMills: Тогда вы просто вызовете super.init() в инициализаторе вашего подкласса. - Даже в ObjC [ASHColorMonochromeFilter filterWithName:... не возвращает экземпляр вашего класса ASHColorMonochromeFilter. - person Martin R; 30.08.2014
comment
И есть проблема - сам суперкласс (CIFilter) не имеет назначенного инициализатора, но init(coder: aDecoder) через принятие NSCoding. Так можно ли позвонить super.init(coder: nil)? - person Ashley Mills; 30.08.2014
comment
@AshleyMills: как я уже сказал, вы просто вызовете super.init в своем инициализаторе подклассов. - person Martin R; 30.08.2014