2017-01-07 8 views
1

Я создал пользовательский подкласс UIView в моем приложении iOS, и я пытаюсь получить рассчитанные размеры представления в методе init, поэтому я могу использовать их при создании подзаголовков внутри пользовательского представления.Получение размера UIView в init

Пользовательский вид находится внутри представления стека, которое присваивает мой вид 1/3 общей высоты (основного вида).

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

var mySubView: UIImageView 

required init?(coder aDecoder: NSCoder) { 

    mySubView = UIImageView() 
    super.init(coder: aDecoder) 

    let viewWidth = Int(self.frame.size.width) 
    let viewHeight = Int(self.frame.size.height) 
    mySubView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight) 
    mySubView.backgroundColor = UIColor.cyan 

    self.addSubview(mySubView) 
} 

Однако, высоты и ширины не сообщается правильно. Например, mySubView выше только заканчивается заполнением около половины от общего объема пользовательского представления.

Любая помощь была бы принята с благодарностью!

+0

Я не думаю, что представление знает, что это размеры в этот момент на протяжении всего жизненного цикла. Попробуйте получить размеры в 'viewWillAppear' – toddg

+4

Вы не можете, а не если это вид контроллера представления. Слишком рано в жизненном цикле контроллера. Вам нужно подождать до (как можно раньше) UIViewController.viewwilllayoutSubviews(). По этой причине вы, вероятно, должны использовать ограничения автоматической компоновки, многие из которых уже обрабатываются представлением стека. Создайте свое собственное представление, добавьте subviews и ограничения (в IB или коде) к пользовательскому представлению, и оно будет раскрывать то, как вам нужно. – dfd

+1

@toddg верен, альтернативой viewWillLayoutSubviews() (используется UIViewController) является viewWillAppear() (используется UIView). Я склонен думать с точки зрения контроллера зрения. ОСТОРОЖНО: Я считаю, что обе функции можно назвать более одного раза при загрузке, а также о таких вещах, как изменения ориентации (и в iPad, многозадачность). – dfd

ответ

1

Инициализатор называется слишком ранним в жизненном цикле представления, чтобы точно выполнить компоновку, если вы заранее не знаете точные размеры. Тем не менее, это идиоматично неправильно место для этого.

Попробуйте использовать метод layoutSubviews как таковой:

class SubView: UIImageView { 

    var mySubView: UIImageView 

    required init?(coder aDecoder: NSCoder) { 

     mySubView = UIImageView() 
     mySubView.backgroundColor = UIColor.cyan 

     super.init(coder: aDecoder) 
     self.addSubview(mySubView) 
    } 

    override func layoutSubviews() { 
     mySubView.frame = self.bounds 
     super.layoutSubviews() 
    } 
} 

Теперь подвид границы будут установлены надлежащим образом в начале каждого макета прохода. Это дешевая операция.

Кроме того, bounds свойство UIView - это frame, переведенное во внутреннее координатное пространство вида. Это означает, что это нормально: bounds = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height). Я предлагаю прочитать документацию по макету вида.

В качестве альтернативы вы можете полностью развернуть макет вручную и использовать AutoLayout для этого.

class SubView: UIImageView { 

    var mySubView: UIImageView 

    required init?(coder aDecoder: NSCoder) { 

     mySubView = UIImageView() 
     mySubView.backgroundColor = UIColor.cyan 

     super.init(coder: aDecoder) 
     self.addSubview(mySubView) 

     mySubView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true 
     mySubView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 
     mySubView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true 
     mySubView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true 
    } 
} 
+0

Спасибо! Я немного упростил этот вопрос для моего вопроса - в моем приложении я не хочу, чтобы какое-либо из подзапросов было полноразмерным, но проблема в том, что мне нужен почти идеальный тонкий контроль над их относительными размерами. Я пытался использовать AutoLayout некоторое время, но я просто не мог заставить его проложить то, что мне нужно, поэтому я решил, что более ручной подход может сэкономить мне некоторое время. :) – rcca

+0

Что бы ни делало для вас человек! Каждая ситуация другая. :) –