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