CALayers не изменилось в соответствии с изменением границ UIView. Зачем?
У меня есть UIView
, который имеет около 8 различных подслоев CALayer
, добавленных к его слою.
Если меняю границы представления (анимированные), то сам вид сжимается (я проверил его с помощью backgroundColor
), но размер подслоев остается неизменным.. p >
Как это решить?
Ответы
Ответ 1
Я использовал тот же подход, что и Солин, но там есть опечатка в этом коде. Метод должен быть:
- (void)layoutSubviews {
// resize your layers based on the view new bounds
mylayer.frame = self.bounds;
}
В моих целях я всегда хотел, чтобы подуровень был полным размером родительского представления. Поместите этот метод в класс вида.
Ответ 2
Так как CALayer на iPhone не поддерживает менеджеров компоновки, я думаю, вам нужно сделать свой основной слой вашего представления подклассом CALayer, в котором вы переопределяете layoutSublayers
для установки фреймов всех подслоев. Вы также должны переопределить метод view +layerClass
, чтобы вернуть класс вашего нового подкласса CALayer.
Ответ 3
Я использовал это в UIView.
-(void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer == self.layer)
{
_anySubLayer.frame = layer.bounds;
}
super.layoutSublayersOfLayer(layer)
}
Работает для меня.
Ответ 4
У меня была та же проблема. В пользовательском слое представления я добавил еще два подслоя. Чтобы изменить размер подслоев (каждый раз, когда изменяются границы пользовательского представления), я реализовал метод layoutSubviews
моего пользовательского представления; внутри этого метода я просто обновляю каждый подслойный фрейм, чтобы соответствовать текущим границам моего уровня subview.
Что-то вроде этого:
-(void)layoutSubviews{
//keep the same origin, just update the width and height
if(sublayer1!=nil){
sublayer1.frame = self.layer.bounds;
}
}
Ответ 5
версия Swift 3
В пользовательской ячейке добавьте следующие строки
Объявить первый
let gradientLayer: CAGradientLayer = CAGradientLayer()
Затем добавьте следующие строки
override func layoutSubviews() {
gradientLayer.frame = self.YourCustomView.bounds
}
Ответ 6
2017
Буквальный ответ на этот вопрос:
"CALayers не изменилось в соответствии с изменением границ UIView. Почему?"
- это то, что лучше или хуже
needsDisplayOnBoundsChange
по умолчанию установлено значение false в CALayer
.
решение
class CircularGradientViewLayer: CALayer {
override init() {
super.init()
needsDisplayOnBoundsChange = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override open func draw(in ctx: CGContext) {
go crazy drawing in .bounds
}
}
В самом деле, я направляю вас к этому QA
fooobar.com/questions/77997/...
который объясняет, что, черт возьми, критическая установка contentsScale
; вам обычно необходимо установить это, когда вы устанавливаете requireDisplayOnBoundsChange.
Ответ 7
Как писал [Ole], CALayer не поддерживает автоматизацию в iOS. Поэтому вы должны настроить макет вручную. Мой вариант состоял в том, чтобы отрегулировать рамку слоя внутри (iOS 7 и ранее)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
или (с iOS 8)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato