开发者

Rotating UIView including the CALayer bounds AND the CALayer frame

开发者 https://www.devze.com 2023-04-01 02:57 出处:网络
I want to rotate my \"containerView\" UIView (semi-transparent red box in the screenshot) using UIDeviceOrientationDidChangeNotification and then later (after it rotates) add sublayers to the view\'s

I want to rotate my "containerView" UIView (semi-transparent red box in the screenshot) using UIDeviceOrientationDidChangeNotification and then later (after it rotates) add sublayers to the view's layer, but I'm finding that only the containerView.layer's bounds are resized, and NOT the containerView.layer's frame! :(

Here's how it looks in portrait:

Rotating UIView including the CALayer bounds AND the CALayer frame

Example code:

- (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.contain开发者_如何学GoerView.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];
    }
}

which, after rotating, prints:

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

(Notice the layer's frame is still 320 wide, 411 high.)

So now it looks like:

Rotating UIView including the CALayer bounds AND the CALayer frame

I also tried setting the center before changing the bounds, but that looks like:

Rotating UIView including the CALayer bounds AND the CALayer frame

I know that the containerView's layer doesn't autoresize, so I tried just setting the layer's frame after the transform... self.containerView.layer.frame = self.containerView.bounds; which then prints out:

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

and looks like:

Rotating UIView including the CALayer bounds AND the CALayer frame

Argh!

autoResizesSubviews is set to YES for all views, clipsToBounds is set to NO. I can't use shouldAutorotateToInterfaceOrientation because the real app will have a camera preview so I want the root view to remain in portrait.

I must be missing something with how I'm doing the transform on containerView to get its layer's bounds and frame to be the same, but I can't figure out what it is! Any help would be much appreciated.

Update - Fixed:

Setting the newly added layer's bounds (testLayer.bounds) to contentView.layer.bounds INSTEAD of contentView.layer.frame did the trick. (Since transforming the contentView invalidates its layer.frame.) Thanks Michael!

Fixed:

Rotating UIView including the CALayer bounds AND the CALayer frame


  self.containerView.bounds = CGRectMake(0, 0, 411.0, 320.0);

Your setting here is wrong because of the flipped context. You set it to be wide and because it is flipped 90 degrees it goes back to being vertical.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号