Вращающийся UIView, включая границы CALayer И рамку CALayer - PullRequest
0 голосов
/ 01 сентября 2011

Я хочу повернуть свой UIView «containerView» (полупрозрачное красное поле на скриншоте), используя UIDeviceOrientationDidChangeNotification, а затем позже (после его поворота) добавить подслои в слой представления, но я обнаружил, что только containerViewРазмеры слоя .layer изменяются, а НЕ рамка containerView.layer!: (

Вот как это выглядит на портрете:

portrait

Пример кода:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)viewDidAppear:(BOOL)animated
{
    CALayer *r = [CALayer layer];
    r.frame = CGRectMake(0, 0, 100, 100);
    r.contents = (id)[[UIImage imageNamed:@"r.png"] CGImage];
    [self.containerView.layer addSublayer:r];
}

- (void)deviceRotated:(NSNotification *)notification
{
    ...
    if (orientation == UIDeviceOrientationLandscapeLeft) {
        self.containerView.transform = CGAffineTransformMakeRotation(RADIANS(90));
        self.containerView.bounds = CGRectMake(0, 0, 411.0, 320.0);

        NSLog(@"container bounds: %@", NSStringFromCGRect(self.containerView.bounds));
        NSLog(@"container layer frame: %@", NSStringFromCGRect(self.containerView.layer.frame));
        NSLog(@"container layer bounds: %@", NSStringFromCGRect(self.containerView.layer.bounds));

        CALayer *testLayer = [CALayer layer];
        testLayer.backgroundColor = [[UIColor blueColor] CGColor];
        testLayer.bounds = self.containerView.layer.frame;
        testLayer.position = CGPointMake(CGRectGetMidX(testLayer.bounds), CGRectGetMidY(testLayer.bounds));
        [self.containerView.layer addSublayer:testLayer];
    }
}

, который после вращения печатает:

container bounds: {{0, 0}, {411, 320}}
container layer frame: {{0, 0}, {<b>320, 411</b>}}
container layer bounds: {{0, 0}, {411, 320}}

(Обратите внимание, что рамка слоя все еще имеет ширину 320, высоту 411).

Так что теперь это выглядит так:

landscape left

Iтакже пытался установить центр перед изменением границ, но это выглядит так:

landscape left with setting center

Я знаю, что слой containerView не изменяет размеры автоматически, поэтому я попытался просто установить кадр слоя послепреобразование ... self.containerView.layer.frame = self.containerView.bounds;, которое затем распечатывает:

container bounds: {{0, 0}, {320, 411}}
container layer frame: {{0, 0}, {411, 320}}
container layer bounds: {{0, 0}, {320, 411}}

и выглядит так:

landscape left and setting layer frame

Argh!

autoResizesSubviewsдля всех представлений установлено значение YES, для clipsToBounds установлено значение NO. Я не могу использовать shouldAutorotateToInterfaceOrientation, потому что реальное приложение будет иметь предварительный просмотр камеры, поэтому я хочу, чтобы корневой вид оставался портретным.

Я долженчто-то упустить из-за того, как я делаю преобразование в containerView, чтобы границы и кадр его слоя были одинаковыми, но я не могу понять, что это такое!Любая помощь будет принята с благодарностью.

Обновление - Исправлено:

Установка границ только что добавленного слоя (testLayer.bounds) на contentView.layer.bounds ВМЕСТО contentView.layer.frame сделалтрюк.(Поскольку преобразование contentView делает недействительным его layer.frame.) Спасибо, Майкл!

Исправлено:

contentView.layer.bounds instead of contentView.layer.frame

1 Ответ

2 голосов
/ 01 сентября 2011
  self.containerView.bounds = CGRectMake(0, 0, 411.0, 320.0);

Ваши настройки здесь неверны из-за перевернутого контекста. Вы устанавливаете его широким, и, поскольку он перевернут на 90 градусов, он возвращается в вертикальное положение.

...