Вопрос

У меня есть собственное представление, которое не получается layoutSubview сообщения во время анимации.

У меня есть представление, которое заполняет экран.У него есть настраиваемое подпредставление в нижней части экрана, размер которого правильно изменяется в Interface Builder, если я меняю высоту панели навигации. layoutSubviews вызывается при создании представления, но никогда снова.Мои подпредставления расположены правильно.Если я отключу строку состояния во время вызова, подпредставление layoutSubviews вообще не вызывается, хотя основное представление анимирует его изменение размера.

При каких обстоятельствах layoutSubviews правда звонил?

У меня есть autoresizesSubviews установлен в NO для моего индивидуального просмотра.А в Interface Builder у меня установлены верхняя и нижняя стойки и вертикальная стрелка.


Другая часть пазла заключается в том, что окно нужно сделать ключевым:

[window makeKeyAndVisible];

в противном случае размер подпредставлений не изменяется автоматически.

Это было полезно?

Решение 5

Я нашел решение в том, что Interface Builder настаивал на том, что пружины нельзя изменять в представлении, в котором включены моделируемые элементы экрана (строка состояния и т. д.).Поскольку для основного представления были отключены пружины, оно не могло изменить размер и, следовательно, было полностью прокручено вниз при появлении панели вызова.

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

Дополнительная проблема при отладке заключается в том, что симулятор выходит из приложения, когда статус вызова переключается через меню.Выйти из приложения = нет отладчика.

Другие советы

У меня был аналогичный вопрос, но ответ меня не удовлетворил (или тот, который я смог найти в сети), поэтому попробовал на практике и вот что получил:

  • init не вызывает layoutSubviews Называться (дух)
  • addSubview: причиныlayoutSubviews Для призывы к добавлению представления, представление, которое он добавляется в (целевой вид), и все подвесы цели
  • вид setFrameразумно звонит layoutSubviews На представлении с установкой кадров, только если параметр размера кадра отличается
  • прокрутка uiscrollview причин layoutSubviews быть вызванным на ScrollView и его присмотр
  • вращение устройства только звонитlayoutSubview На родительском представлении (Основное представление ViewControllers)
  • Изменение размера представления вызовет layoutSubviews на его супервью

Мои результаты - http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get- Called/

Основываясь на предыдущем ответе @BadPirate, я поэкспериментировал еще немного и внес некоторые уточнения/исправления.я нашел это layoutSubviews: будет вызываться для представления тогда и только тогда, когда:

  • Свой собственный границы (не рама) изменена.
  • Изменились границы одного из его прямых подпредставлений.
  • Подпредставление добавляется в представление или удаляется из представления.

Некоторые важные детали:

  • Границы считаются измененными, только если новое значение отличается, включая другое происхождение.Обратите внимание, именно поэтому layoutSubviews: вызывается всякий раз, когда UIScrollView прокручивает, поскольку он выполняет прокрутку, изменяя начало своих границ.
  • Изменение рамки приведет к изменению границ только в том случае, если изменился размер, поскольку это единственное, что передается свойству границ.
  • Изменение границ представления, которого еще нет в иерархии представлений, приведет к вызову layoutSubviews: когда представление в конечном итоге добавляется в иерархию представлений.
  • И просто для полноты:эти триггеры не напрямую вызовите LayoutSubviews, а скорее вызовите setNeedsLayout, который устанавливает/поднимает флаг.Каждая итерация цикла выполнения для всех представлений. в иерархии представлений, этот флаг установлен.Для каждого просмотра, где обнаружен поднятый флаг, layoutSubviews: на нем вызывается и флаг сбрасывается.Представления выше по иерархии будут проверены/вызваны в первую очередь.

https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1

Изменения макета могут происходить, когда какое -либо из следующих событий происходит в представлении:

а.Размер прямоугольника границ представления изменится.
б.Происходит изменение ориентации интерфейса, что обычно вызывает изменение прямоугольника границ корневого представления.
в.Набор подслоев базовой анимации, связанных со слоем представления, изменяется и требует макета.
д.Ваше приложение принудительно выполняет макет, вызывая методsetNeedsLayoutилиlayoutIfNeededметод взгляда.
е.Ваше приложение принудительно выполняет макет, вызывая методsetNeedsLayoutметод объекта базового слоя представления.

Некоторые моменты в Ответ BadPirate верны лишь частично:

  1. Для addSubView точка

    addSubview вызывает вызов LayoutSubviews для добавляемого представления, представления, в которое оно добавляется (целевое представление), и всех подпредставлений целевого объекта.

    Это зависит от маски автоматического изменения размера представления (целевого представления).Если у него включена маска автоматического изменения размера, LayoutSubview будет вызываться для каждого addSubview.Если у него нет маски автоматического изменения размера, то LayoutSubview будет вызываться только тогда, когда изменится размер кадра представления (целевого представления).

    Пример:если вы создали UIView программно (по умолчанию у него нет маски автоматического изменения размера), LayoutSubview будет вызываться только при изменении кадра UIView не при каждом addSubview.

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

  2. Для точки вращения устройства

    Вращение устройства вызывает только LayoutSubview в родительском представлении (основном представлении отвечающего viewController).

    Это может быть правдой только тогда, когда ваш виртуальный капитал находится в иерархии виртуальных каналов (корневой каталог window.rootViewController), ну это самый распространенный случай.В iOS 5, если вы создаете виртуальный виртуальный компьютер, но он не добавляется ни в один другой виртуальный виртуальный компьютер, то этот виртуальный виртуальный компьютер не будет замечен при повороте устройства.Поэтому его представление не будет замечено при вызове LayoutSubviews.

звоню[self.view setNeedsLayout]; в viewController позволяет вызывать viewDidLayoutSubviews

вы смотрели макетIfNeeded?

Фрагмент документации приведен ниже.Работает ли анимация, если вы явно вызываете этот метод во время анимации?

MayOuteFneed излагает подвесимости, если это необходимо.

- (void)layoutIfNeeded

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

Доступность в iPhone OS 2.0 и позже.

При переносе приложения OpenGL с SDK 3 на 4 LayoutSubviews больше не вызывался.После долгих проб и ошибок я наконец открыл MainWindow.xib, выбрал объект Window, в инспекторе выбрал вкладку «Атрибуты окна» (крайнюю левую) и установил флажок «Видимый при запуске».Кажется, что в SDK 3 он все еще вызывал вызов LayoutSubViews, но не в 4.

6 часов разочарования подошли к концу.

Довольно малоизвестный, но потенциально важный случай, когда layoutSubviews никогда не вызывается:

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top