Добавление дополнительного кода инициализации в унаследованный инициализатор от суперкласса

У меня есть класс Swift UIView (с именем HypnosisView), который рисует круг на экране. Рамка представления настроена так, чтобы заполнить экран. Я хотел бы программно установить цвет фона представления при инициализации (поэтому, когда создается экземпляр представления, он автоматически имеет указанный цвет фона). Я смог сделать эту работу с помощью удобного инициализатора, однако мне интересно, есть ли более эффективный способ сделать это (или на самом деле я делаю это правильно). В идеальном сценарии я хотел бы просто добавить фрагмент кода, устанавливающий background: self.background = UIColor.clearColor(), к унаследованному методу init(frame: CGRect), поэтому мне не нужно писать полностью новый инициализатор только для установки цвета фона.
Вот мой удобный метод инициализации (то, что я сейчас использую, что работает):

convenience init(rect: CGRect){
        self.init(frame: rect)
        self.backgroundColor = UIColor.clearColor()
}

и я вызываю этот метод в делегате следующим образом:

var mainFrame = self.window!.bounds
var mainView = HypnosisView(rect: mainFrame)

Дайте знать, если у вас появятся вопросы. Спасибо!


person dcgoss    schedule 09.08.2014    source источник
comment
Почему вы используете удобный инициализатор? Вы уже подкласс UIView. В его назначенном инициализаторе установите цвет фона. Но в основном это именно то, что вы делаете (за исключением удобства), и я не вижу, как вы можете сделать это короче. Весь ваш новый инициализатор — это просто вызов супер и ваших собственных модификаций.   -  person Rikkles    schedule 10.08.2014
comment
@Rikkles Я пытался переопределить назначенный инициализатор следующим образом: override init(frame: CGRect){ self.backgroundColor = UIColor.clearColor() <return key> super.init(frame: frame)}, и он выдал ошибку: Class "HypnosisView" does not implement its superclass's required members, поэтому я попробовал удобный инициализатор. я все еще учусь всему этому   -  person dcgoss    schedule 10.08.2014
comment
На самом деле я беру это обратно. Если вы используете удобный инициализатор, это самое простое. Потому что, если вы переопределяете init(frame), вы также должны переопределять init(coder), что создает для вас больше кода. Так что в вашем случае я думаю, что у вас есть самое простое решение. Удобный инициализатор, который устанавливает для свойства значение по умолчанию.   -  person Rikkles    schedule 10.08.2014
comment
+1 Большое спасибо! @Рикклес   -  person dcgoss    schedule 10.08.2014


Ответы (1)


Как обсуждалось в комментариях, при желании настроить поведение UIView часто проще использовать инициализатор convenience, а не переопределять назначенный инициализатор.

В частности, для UIViews, если вы переопределяете назначенный init(frame aRect: CGRect), вам, к сожалению, также необходимо переопределить init(coder decoder: NSCoder!), который является частью протокола NSCoding. Поэтому, как правило, если вы просто хотите установить для некоторых свойств некоторые значения по умолчанию, сделайте так, как просил исходный постер, и создайте удобный инициализатор, который, в свою очередь, вызывает init(frame aRect: CGRect):

convenience init(rect: CGRect, bgColor: UIColor){
    self.init(frame: rect)
    self.backgroundColor = bgColor
}

Обсуждение избавления от соответствия NSCoding см. в разделе . реализовать обязательные члены своего суперкласса

person Rikkles    schedule 09.08.2014
comment
Один вопрос: что значит, когда у вас два имени параметра, когда вы говорите init(frame aRect: CGRect) ? - person dcgoss; 10.08.2014
comment
Означает, что внешне параметр называется frame, но внутри функции он называется aRect. См. Имена внешних параметров в книге Swift. - person Rikkles; 10.08.2014