Подтвердить что ты не робот

IOS AutoLayout - получить размер кадра

Я занимаюсь разработкой с использованием макета iOS 6

Я хотел бы записать сообщение, отображающее ширину рамки представления.

Я вижу textView на экране.

Но я получаю ширину и высоту как ноль, я что-то пропустил?

NSLog(@"textView    = %p", self.textView);
NSLog(@"height      = %f", self.textView.frame.size.height);
NSLog(@"width       = %f", self.textView.frame.size.width);

textView    = 0x882de00
height      = 0.000000
width       = 0.000000
4b9b3361

Ответ 1

Я думаю, что автоматическая компоновка не имела времени для компоновки ваших просмотров к тому времени, когда вы это называете. Автоматическая компоновка не произошла к моменту вызова viewDidLoad, потому что она вызывалась сразу после загрузки представлений, и только после этого представления помещаются в иерархию представлений контроллера представления и в конечном итоге выкладываются (в представлении layoutSubviews).

Изменить: этот ответ указывает, почему сценарий в вопросе не работает. @dreamzor answer указывает, где разместить свой код, чтобы его решить.

Ответ 2

Собственно, ответы выше не совсем правильные. Я последовал за ними и получил нули снова и снова.

Трюк заключается в том, чтобы поместить ваш зависимый от кадра код в метод viewDidLayoutSubviews, который

Сообщает диспетчеру просмотра, что его представление просто выложило его подпрограммы.

Не забывайте, что этот метод вызывается несколько раз и не является частью жизненного цикла ViewController, поэтому будьте осторожны при использовании этого.

Надеюсь, что это будет полезно кому-то.

Просто хотел добавить, что для моей программы без ландшафтного режима НЕ использовать Auto Layout намного проще... Я пробовал, хотя = D

Ответ 3

Решение

  • Поместите этот код в viewDidAppear

Причина

  • viewDidLoad происходит до завершения автозапуска. Таким образом, позиция еще не установлена ​​автозапуском, которое было указано в xib
  • viewDidAppear происходит после завершения автозапуска.

Ответ 4

Включить в свой viewDidLoad()

self.view.setNeedsLayout()
self.view.layoutIfNeeded()

Перед доступом к файлу yourview.frame.size.width

Ответ 5

На самом деле мне удалось принудительно обновить макет перед моим кодом в viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()

        println("bounds before \(self.previewContainer.bounds)");
        //on iPhone 6 plus -> prints bounds before (0.0,0.0,320.0,320.0)

        self.view.setNeedsLayout()
        self.view.layoutIfNeeded()

        println("bounds after \(self.previewContainer.bounds)");
        //on iPhone 6 plus -> prints bounds after (0.0,0.0,414.0,414.0)

        //Size dependent code works here
        self.create()
    }

UPDATE: это больше не работает

Ответ 6

Это действительно странная функция. Но я обнаружил:

Если вы хотите получить кадр без использования метода layoutsubviews, используйте этот:

dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"View frame: %@", NSStringFromCGRect(view.frame));
    });

Это действительно странно!!!

Ответ 7

Ни один из вышеперечисленных ответов не работал полностью для меня, кроме viewDidLoad, но имеет побочный эффект, не отображающий то, что я хочу, до тех пор, пока анимированный вид не будет выглядеть.

viewDidLayoutSubviews должно быть правильным местом для запуска кода, который полагается на завершение автоопределения, но, как указывали другие, он вызывается несколько раз в последних версиях iOS, и вы не можете знать, что является последним вызовом.

Итак, я решил это с небольшим взломом. В моем раскадровке mySubview должен быть меньше, чем содержать self.view. Но когда viewDidLayoutSubviews сначала вызывается, mySubview по-прежнему имеет ширину 600, а self.view, кажется, правильно настроен (это проект iPhone). Поэтому мне нужно только следить за последующими вызовами и проверять относительную ширину. Если mySubview меньше, чем self.view, я могу быть уверен, что он был правильно установлен.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if self.mySubview.bounds.size.width < self.view.bounds.size.width {

        // mySubview width became less than the view width, so it is
        // safe to assume it is now laid out correctly...

    }
}

Это имеет то преимущество, что не полагается на жестко закодированные номера, поэтому может работать, например, со всеми форматирующими факторами iPhone. Конечно, это не может быть панацеей во всех случаях или на всех устройствах, но, вероятно, существует множество изобретательных способов сделать аналогичные проверки относительных размеров.

И нет, мы не должны этого делать, но пока Apple не дает нам более надежных обратных вызовов, мы все застряли.

Ответ 8

iOS AutoLayout - размер рамки кадра

 -(void) layoutSubviews{
        [self layoutIfNeeded];
        //right you code to set frame its will work to get frame and set frame.
        CALayer *bottomBorder = [CALayer layer];
        bottomBorder.frame = CGRectMake(0.0f, bkView.frame.size.height - 1, bkView.frame.size.width, 1.0f);
        bottomBorder.backgroundColor = [UIColor blackColor].CGColor;
        [bkView.layer addSublayer:bottomBorder];
    }

Ответ 9

Вы можете узнать размер только после первого прохода макета. Или просто вызовите метод ниже, после того, как вы получили фактическую ширину просмотра.

[yourView layoutIfNeeded];