Как написать пользовательский init для подкласса UIView в Swift?



скажи, что я хочу init a UIView подкласс с String и Int.



как бы я сделал это в Swift, если я просто подкласс UIView? Если я просто сделать заказ init() функция, но параметры-это строка и Int, это говорит мне, что " супер.init () не вызывается перед возвращением из инициализатора".



а если я позвоню super.init() мне сказали, что я должен использовать назначенный инициализатор. Что я должен использовать здесь? Версия кадра? Версия кодера? Как? Зачем?

729   5  

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

    Ничего не найдено.