views:

33

answers:

2

I need to rotate and move objects on a UIView when the orientation changes. To that end I have the following in willRotateToInterfaceOrientation

if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
    [self repositionObjectAfterRotation:scrollView x:0 y:100 width:480 height:150];
    [self repositionObjectAfterRotation:pageControl x:50 y:430 width:100 height:30];    
}

My repositionObjectAfterRotation:x:y:width:height: looks like this, which takes the object and alters its bounds, before setting the new bounds.

- (void)repositionObjectAfterRotation:(UIView *)anObject x:(int)x y:(int)y 
                                     width:(int)width height:(int)height
{   

    [UIView animateWithDuration:kAnimationDuration animations:^{
        CGRect boundsRect = anObject.bounds;
        boundsRect.origin.x = x;
        boundsRect.origin.y = y;
        boundsRect.size.width = width;
        boundsRect.size.height = height;
        anObject.bounds = boundsRect;
    } completion:^ (BOOL finished){
        if (finished) {
            [UIView animateWithDuration:kAnimationDuration animations:^{
                anObject.alpha = 1.0;
            }];
        }
    }];

}

When the view rotates back to portrait, it only displays half of the scrollview, even though my NSLogs state that the frame & bounds are correct...

Am I rotating / repositioning objects correctly or is there an easier/preferred way to support landscape?

Thanks

A: 

You are explicitly setting the height to "150" when you rotate to Landscape, but don't adjust it back when you go back to portrait.

I don't know how your auto-sizing is set-up in IB, so I can't state how these objects will resize/move when left by themselves.

Brad
Sorry it does move back in portrait, copy and paste error. My bad. In IB all the struts and springs are selected.
joec
A: 

3 points:

  1. you don't need to explicitly begin an animation, system will do it anyway (unless your animation is "different from rotation."
  2. I think overriding layoutSubviews is more convenient. It's called after each rotation, and [device orientation] gives you the new orientation.
  3. You probably want to change the frame of these views, not their bounds, which is an internal value (i.e. it matters only "inside" that view).

frame says 'put me in this position of the superivew', which is what you want. bound defines the coordinate your, say, scrollView uses for its subviews. what you need here is the frame.

In layoutSubviews, just change the frame, the animation you want will apply automatically:

- (void)layoutSubviews {
    if (UIInterfaceOrientationIsLandscape([[UIDevice currentDevice] orientation])) {
        anObject.frame = landscapeFrame;
    }
    else {
        anObject.frame = portraitFrame;
    }
}
Mo
The `frame` is in relation to the superview coordinates isn't it? Overriding layoutSubviews is something i have never done before. Do I just override `layoutSubviews` and put my movement code there? Nothing special? I want to animate because my items dont just rotate i.e. i have a scrollview which needs to more from 0,80 to 0,100 when rotated.
joec
updated the answer, hope it helps ;-)
Mo
`layoutSubviews` is not called when the view rotates... I tried calling `[self.view setNeedsLayout];` in `willRotateToIntefaceOrientation` but it still didnt enter my method
joec
hmm... I'm using this method daily... and in the worst case `layoutSubviews` should be invoked when `setNeedsLayout` is called. I assume you've checked `layoutSubviews` is properly implemented in your view?
Mo