Ответ
Позиция sublayer определяется через геометрические свойства CALayer:
Основные свойства:
frame— прямоугольник в координатах superlayer (вычисляемое свойство)bounds— прямоугольник в собственных координатахposition— точка привязки в координатах superlayeranchorPoint— точка нормированных координат (0.0-1.0) внутри bounds
Пример установки позиции:
let sublayer = CALayer()
// Способ 1: Через frame
sublayer.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
// Способ 2: Через position и bounds (рекомендуется для анимаций)
sublayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
sublayer.position = CGPoint(x: 70, y: 70) // Центр при anchorPoint (0.5, 0.5)
sublayer.anchorPoint = CGPoint(x: 0.5, y: 0.5) // По умолчанию
Важные взаимосвязи:
// frame вычисляется как:
frame.origin = position - (bounds.size * anchorPoint)
frame.size = bounds.size
// При изменении frame обновляются position и bounds
// При изменении position или bounds обновляется frame
Рекомендации:
- Для анимаций используйте
positionиtransform(аппаратное ускорение) - Избегайте анимации
frame— это приводит к пересчёту position и bounds anchorPoint(0, 0) — верхний левый угол, (1, 1) — нижний правый
Ответ 18+ 🔞
Да ты посмотри, на что люди время тратят! Весь этот пиздец с CALayer... Ну ладно, слушай сюда, раз уж начал.
Вот есть у тебя эта sublayer, да? И её, сука, куда-то надо приткнуть. Так вот, позиция её — это не просто "ах, поставь её там, где хочешь". Это, блядь, целая наука, построенная на четырёх китах, которые друг другу мозги ебут.
Смотри, основные игроки на поле:
frame— это как бы итоговый прямоугольник, но он вычисляемый, чувак. То есть он сам из других свойств складывается, как пазл. Не ты его задаёшь, а он тебе выдаётся, исходя из всей этой хуйни ниже.bounds— это её личные владения, её внутренняя система координат. Обычно ноль-ноль в левом верхнем углу, но можешь и сдвинуть, если хочешь с ума сойти.position— это, внимание, точка привязки в координатах слоя-родителя (тогоsuperlayer). Ключевое слово!anchorPoint— а это, блядь, нормированная точка внутри самого слоя, за которую его таскают. По умолчанию (0.5, 0.5) — центр. Сделаешь (0,0) — будешь таскать за верхний левый угол. Гениально и просто, как хуй в проруби.
Вот как это на практике выглядит:
let sublayer = CALayer() // Родился, сука, ни рыба ни мясо.
// Способ 1: По-деревенски, через frame. Быстро и грубо.
sublayer.frame = CGRect(x: 20, y: 20, width: 100, height: 100) // Готово. Сиди там.
// Способ 2: По-взрослому, как джедай. Для анимаций — самое то.
sublayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100) // Задал свои размеры.
sublayer.position = CGPoint(x: 70, y: 70) // Сказал, где в координатах родителя будет anchorPoint.
sublayer.anchorPoint = CGPoint(x: 0.5, y: 0.5) // А это и есть та самая точка (центр). По умолчанию и так стоит.
А теперь, блядь, магия их взаимоотношений (держись за стул):
// frame — это производная, ёпта! Он вычисляется так:
frame.origin = position - (bounds.size * anchorPoint) // Вот эта хуйня!
frame.size = bounds.size
// И обратная ебля:
// Поменял frame — система за тебя пересчитает position и bounds.
// Поменял position или bounds — система обновит frame.
Итоговые рекомендации, чтобы не выстрелить себе в ногу:
- Хочешь анимировать движение? Юзай
positionиtransform. Это железо ускоряет, летает, как угорелое. - Избегай как чумы анимации самого
frame. Это пиздец, потому что система будет на каждом кадре пересчитывать иposition, иbounds— производительность накроется медным тазом. - Запомни про
anchorPoint: (0, 0) — таскаешь за верхний левый угол, (1, 1) — за нижний правый. Поиграйся, почувствуй силу.
Вот и вся философия. Не так страшен чёрт, как его CALayer.