2016-08-13 2 views
0

Так вот нет вещь, я объявляю свойство как это:При использовании переменной вычислен и Snapkit: Нет общего SuperView между видами

var aNameLabel: UILabel { 
    guard let foo = Applicant.sharedInstance.realName else { 
     return UILabel(text: "获取姓名失败", color: .whiteColor()) 
    } 
    return UILabel(text: foo, color: .whiteColor()) 
} 

И когда я пытаюсь добавить ограничение на aNameLabel после того как я сделал someView.addSubView(aNameLabel) , приложение будет врезаться каждый раз, когда на это ограничение, добавив вещи, и говорит No common superview between views

Однако, когда я изменить переменную в константу пусть так:

let aNameLabel = UILabel(text: "Allen", color: .whiteColor())

Ограничение будет добавлено без каких-либо претензий. Кто-нибудь может мне помочь?

UPDATE

С помощью @par, я изменил свой код в этом:

var aNameLabel: UILabel = { 
    guard let foo = Applicant.sharedInstance.realName else { 
     return UILabel(text: "BAD", color: .whiteColor()) 
    } 
    return UILabel(text: foo, color: .whiteColor()) 
}() 

И тогда aNameLabel всегда будет назначена со значением «BAD», в то время как на самом деле мой guard let успешный. Как это исправить?

ответ

1

Проблема заключается в том, что вы создаете новый UILabel каждый раз, когда вы обращаетесь к переменной aNameLabel (функция вычисляемого свойства запускается каждый раз при ее доступе). Предположительно, вы делаете то же самое для просмотра этого вида (при доступе в someView.addSubview() в приведенном выше примере). Если это так, вот почему нет обычного супервизора, и вы рушитесь.

Вы должны создать только один экземпляр каждого UIView используемого контроллера представления, создавая таким образом переменную как константу, как вы показали это отличный подход, или вы можете использовать шаблон затворных инициализатора следующим образом:

var aNameLabel: UILabel = { 
    return UILabel(...) 
}() 

Обратите внимание, что в приведенном выше примере скобки после закрывающей скобки. Поскольку это инициализатор закрытия, он будет вызываться только один раз, как константа let.

Часто UIView создан с let не подходит, потому что постоянные свойства должны быть инициализирована до init() возвращается, и если вы создаете взгляды в контроллере представления не будет иметь возможность добавить взгляды, пока loadView() не называется , В этом случае объявите свои UIView s как неявно-развернутые опции. Они будут установлены в nil по init(), который отвечает требования инициализации, то вы можете установить их действительные взгляды позже, когда viewDidLoad() называется, например:

class MyViewController: UIViewController { 
    var someSubview: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     someSubview = UIView() 
     view.addSubview(someSubview) 
     // now set constraints with SnapKit 
    } 
} 
+0

Благодаря Mate! Это действительно помогло! Но у меня все еще есть проблема. Пожалуйста, прочтите мое обновление. – Allen

+0

Привет, я только что обновил его – Allen

+0

Привет, я просто решил инициализировать значение в 'viewDidLoad()'. Проблема решена. Я просто хотел, чтобы мой 'viewDidLoad()' был проще и присвоить значения правой стороне, когда они объявляются. – Allen