У мене була подібна проблема - необхідність встановити фрейм "CALayer" при використанні автоматичного макетування з поданнями (у коді, а не IB ).
У моєму випадку я мав дещо заплутану ієрархію, маючи контролер перегляду всередині контролера перегляду. Я опинився на цьому SO-питанні і розглянув підхід використання viewDidLayoutSubviews
. Це не спрацювало. На випадок, якщо ваша ситуація схожа на мою, ось що я знайшов ...
Огляд
Я хотів би встановити рамки для CAGradientLayer
оператора А , UIView
що я позиціонував як підвид в межах з UIViewController
допомогою обмежень автоматичної компонування.
Викличте підзапис gradientView
та контролер перегляду child_viewController
.
child_viewController
був контролером перегляду, який я встановив як свого роду повторно використовуваний компонент. Отже, view
компонент child_viewController
компонувався у батьківський контролер подання - зателефонуйте parent_viewController
.
Коли viewDidLayoutSubviews
з child_viewController
називали, то frame
з gradientView
ще не був встановлений.
(На цьому етапі я рекомендую посипати деякі NSLog
твердження навколо, щоб відчути послідовність створення поглядів у вашій ієрархії тощо).
Тож я перейшов на спробу використання viewDidAppear
. Однак через вкладений характер child_viewController
мене знайшли viewDidAppear
не викликали.
(Див. Це запитання SO: viewWillAppear, viewDidAppear не викликається, не запускається ).
Моє поточне рішення
Я додав viewDidAppear
у parent_viewController
і звідти я дзвоню viewDidAppear
в child_viewController
.
Для початкового завантаження мені потрібно, viewDidAppear
оскільки це не відбувається, поки це не буде викликано child_viewController
, і всі підпрогляди мають встановлені кадри. Потім я можу встановити рамку для CAGradientLayer
...
Я сказав, що це моє поточне рішення, тому що я не особливо ним задоволений.
Після початкового встановлення кадру CAGradientLayer
- цей кадр може стати недійсним у разі зміни макета - наприклад, обертаючи пристрій.
Щоб впоратися з цим, я використовую viewDidLayoutSubviews
в child_viewController
- щоб зберегти рамку CAGradientLayer
всередині gradientView
, правильно.
Це працює, але не відчуває себе добре. (Чи є кращий спосіб?)