Как заставить тень UIView растягиваться при повороте устройства?

В настраиваемой ячейке табличного представления я рисую простой прямоугольник с такой тенью:

photoBorder = [[[UIView alloc] initWithFrame:CGRectMake(4, 4, self.frame.size.width-8, 190)] autorelease];
photoBorder.autoresizingMask = UIViewAutoresizingFlexibleWidth;
photoBorder.backgroundColor = [UIColor whiteColor];
photoBorder.layer.masksToBounds = NO;
photoBorder.layer.shadowOffset = CGSizeMake(0, 1);
photoBorder.layer.shadowRadius = 4;
photoBorder.layer.shadowOpacity = 1.0;
photoBorder.layer.shadowColor = [UIColor darkGrayColor].CGColor;
photoBorder.layer.shouldRasterize = YES;
photoBorder.layer.shadowPath = [UIBezierPath bezierPathWithRect:photoBorder.bounds].CGPath; // this line seems to be causing the problem

Это прекрасно работает, когда представление загружается впервые. Однако при повороте устройства тень остается того же размера. Мне бы очень хотелось, чтобы он растянулся до новой ширины "photoBorder".

Я могу заставить его работать, удалив shadowPath, но табличное представление принимает заметное снижение производительности.

У кого-нибудь есть советы по созданию тени в UIView, которая может растягиваться без потери производительности?

2 ответа

После поиска в течение нескольких часов и не найдя ничего, я отправил это. Затем нашли ответ через несколько минут.

Мне кажется, что простым решением является просто перемещение shadowPath в layoutSubviews.

- (void)layoutSubviews{
    photoBorder.layer.shadowPath = [UIBezierPath bezierPathWithRect:photoBorder.bounds].CGPath;
}

Вам нужно создать подкласс UIView, чтобы вы могли получить новые границы в layoutSubviews() метод.

Примечание. Если вы попытаетесь добавить этот код в ViewController, которому принадлежит подпредставление, границы будут оставаться статичными при повороте, что приведет к неверному shadowPath.

import UIKit

class BackgroundView: UIView {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        updateShadow(on: self)
    }

    func updateShadow(on background: UIView) {
        let layer = background.layer
        layer.shadowPath = UIBezierPath(rect: background.bounds).cgPath
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 2)
        layer.shadowRadius = 4
        layer.shadowOpacity = 0.22
    }

}
  1. Убедитесь, что вы звоните super.layoutSubviews() обрабатывать любые ограничения Auto Layout.

  2. Вы можете установить пользовательский класс в файле раскадровки.

Для повышения производительности вы можете нарисовать внутреннюю тень, используя Core Graphics.

Эффект внутренней тени на слое UIView

Другие вопросы по тегам