Placing and Moving Views on Rotation (UIView)

2019-02-01 10:13发布

What's the "correct" way of exactly placing and moving views when an app rotates? That is, how can I have fine-grained control of the position, size, and reflow of my views when the UI rotates from portrait to landscape orientation (or vice-versa)? I think my two options are:

  1. Use two superviews (portrait and landscape). On rotation: toggle between them.
  2. Use one superview. On rotation: change each subview's frame, bounds, and center properties.

If you have two views with distinct enough layouts and elements, then the first way might be good enough. If your two views are essentially the same thing sized for different orientations, the second way is probably a better way to do it using only one view.

I suspect the former could be done with IB and the latter should be done programmatically.

portrait to landscape

4条回答
贼婆χ
2楼-- · 2019-02-01 10:34

Here's one idea. I worry that the animations will work funny, but try it and see.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
                                duration:(NSTimeInterval)duration {

    if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
        toOrientation == UIInterfaceOrientationLandscapeRight) {
        [UIView beginAnimations:nil context:NULL]; {
            [UIView setAnimationDuration:1.0];
        }
            [UIView setAnimationDelegate:self];
        [viewA setFrame:CGRectMake(?,?,?,?)];
        [viewB setFrame:CGRectMake(?,?,?,?)];
        [viewC setFrame:CGRectMake(?,?,?,?)];
        } [UIView commitAnimations];    
    } else if  (toOrientation == UIInterfaceOrientationPortrait ||
            toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        [UIView beginAnimations:nil context:NULL]; {
            [UIView setAnimationDuration:1.0];
        }
        [UIView setAnimationDelegate:self];
        [viewA setFrame:CGRectMake(?,?,?,?)];
        [viewB setFrame:CGRectMake(?,?,?,?)];
        [viewC setFrame:CGRectMake(?,?,?,?)];
        } [UIView commitAnimations];    
    }
查看更多
放荡不羁爱自由
3楼-- · 2019-02-01 10:42

To have fine-grained control over the position and size of your subviews when the iPhone rotates, change the frame of the subviews in the UIViewController method willAnimateRotationToInterfaceOrientation:duration:. This method is called within an animation block, so all the changes to your subviews' frames that you make inside of it are animated.

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
        // Portrait frames
        self.subviewA.frame = CGRectMake(x, y, width, height);
        self.subviewB.frame = CGRectMake(x, y, width, height);
        self.subviewC.frame = CGRectMake(x, y, width, height);
    } else {
        // Landscape frames
        self.subviewA.frame = CGRectMake(x, y, width, height);
        self.subviewB.frame = CGRectMake(x, y, width, height);
        self.subviewC.frame = CGRectMake(x, y, width, height);
    }
}
查看更多
虎瘦雄心在
4楼-- · 2019-02-01 10:42

There is a lot solutions for that. One of them is animations for controls as you read before. Another option is prepare 2 UIView one for portrait mode and another for landscape mode. And on switch orientation - load proper UIView. That's the way i used in my applications. Because sometimes differences between landscape and portrait is huge.

In simple cases is enough to set up correct autoresizingMask for subviews. Read about it. It works really nice.

查看更多
Animai°情兽
5楼-- · 2019-02-01 10:51

I have an idea which is working properly for me where I am using a small view on a view where it rotates itself when orientation of device changes. Use one notifier then in the method change the orientation.

#define DegreesToRadians(x) (M_PI * x / 180.0)

.......

[[NSNotificationCenter defaultCenter] addObserver:showIndicator
                                         selector:@selector(setProperOreintation)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

.......

-(void)setProperOrientation {

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];


if (orientation == UIDeviceOrientationPortraitUpsideDown)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(180)); 

else if (orientation == UIDeviceOrientationLandscapeLeft)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(90));  

else if (orientation == UIDeviceOrientationLandscapeRight)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(-90));

    [UIView commitAnimations]; }

Here instead of rotate u can use translate or scale

查看更多
登录 后发表回答