Как написать пользовательский init для подкласса UIView в Swift?
скажи, что я хочу init a UIView подкласс с String и Int.
как бы я сделал это в Swift, если я просто подкласс UIView? Если я просто сделать заказ init() функция, но параметры-это строка и Int, это говорит мне, что " супер.init () не вызывается перед возвращением из инициализатора".
а если я позвоню super.init() мне сказали, что я должен использовать назначенный инициализатор. Что я должен использовать здесь? Версия кадра? Версия кодера? Как? Зачем?
5 ответов:
The
init(frame:)версия является инициализатором по умолчанию. Вы должны вызвать его только после инициализации переменных экземпляра. Если это представление восстанавливается из пера, то ваш пользовательский инициализатор не будет вызван, а вместо этогоinit?(coder:)версия будет называться. Поскольку Swift теперь требует реализации требуемогоinit?(coder:), я обновил пример ниже и изменилletобъявления переменныхvarи факультативный. В этом случае вы должны инициализировать их вawakeFromNib()или в какое-то более позднее время.class TestView : UIView { var s: String? var i: Int? init(s: String, i: Int) { self.s = s self.i = i super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } }
вот как я это делаю на iOS 9 в Swift -
import UIKit class CustomView : UIView { init() { super.init(frame: UIScreen.mainScreen().bounds); //for debug validation self.backgroundColor = UIColor.blueColor(); print("My Custom Init"); return; } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); } }вот полный проект с примером:
вот как я делаю Subview на iOS в Swift -
class CustomSubview : UIView { init() { super.init(frame: UIScreen.mainScreen().bounds); let windowHeight : CGFloat = 150; let windowWidth : CGFloat = 360; self.backgroundColor = UIColor.whiteColor(); self.frame = CGRectMake(0, 0, windowWidth, windowHeight); self.center = CGPoint(x: UIScreen.mainScreen().bounds.width/2, y: 375); //for debug validation self.backgroundColor = UIColor.grayColor(); print("My Custom Init"); return; } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented"); } }
создать общие инициализации, для места и требуется. Для удобства inits я делегирую в
init(frame:)С нулевой рамкой.наличие нулевого кадра не является проблемой, потому что обычно представление находится внутри представления ViewController; ваш пользовательский вид получит хороший, безопасный шанс компоновать свои подвиды, когда его супервизор вызывает
layoutSubviews()илиupdateConstraints(). Эти две функции вызываются системой рекурсивно по всей иерархии. Вы можете использовать либоupdateContstraints()илиlayoutSubviews().updateContstraints()вызывается сначала, затемlayoutSubviews(). ВupdateConstraints()обязательно позвоните супер последние. ВlayoutSubviews()вызовите Super первый.вот что я делаю:
@IBDesignable class MyView: UIView { convenience init(args: Whatever) { self.init(frame: CGRect.zero) //assign custom vars } override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() commonInit() } private func commonInit() { //custom initialization } override func updateConstraints() { //set subview constraints here super.updateConstraints() } override func layoutSubviews() { super.layoutSubviews() //manually set subview frames here } }
Я пробовал эти принятые сообщения о настройке init и все еще считаю, что они сложны для реализации и вызова из других частей вашего кода. Таким образом, только для некоторых новичков, таких как я, которые предпочитают использовать раскадровку для индивидуального просмотра:
вы можете настроить эти свойства, добавив атрибут @IBInspectable в начале их объявлений и изменить их значения в верхней части инспектора атрибутов XCode. Наконец, не забудьте добавить property observer к вызовите настроенное поведение для этих проверяемых свойств. Наблюдатель вызывается при загрузке XIB вместо инициализации.
Comments