Device Rotation


#1

I have a sliding overlay with a grid on the overlay.  The menu on the underlay changes which grid is displayed on the overlay.  I want to resize the grid to the new orientation.  What is the best way to implement this?

I am adding a grid using:

 [slidingView.overlayaddSubview:[orderGridViewControllerview]];

If I add:

  [selfaddChildViewController:(UIViewController*) orderGridViewController];

the subview picks up rotation events in didRotateFromInterfaceOrientation but I'm not sure how to correctly apply this.


#2

Question revisited.  Here is the example of rotation failing, using the basic examples for the sliding view and the grid, with pretty Christmas  background colors (red underlay/green overlay), and a grain-white background image on the grid view.  Run it, rotate it all 4 directions - seems to work.  Show the underlay, rotate it, and notice the overlay isn’t setting up correctly.  Change the grid, rotate, both with and without the underlay, and you can get some really interesting sizing effects on the grid.

http://www.cattail.nu/temp/rotationProblem.zip

How should I implement the views correctly to handle rotation?


#3

Greetings Program!

I’m not sure if this is the best way to do it but how about when the orientation changes, then remove the grid and recreate it with the column widths for that orientation. Maybe something like this:

EDIT NOTE: I tested this with your app and it works.

- (void)viewDidLoad
{
	[super viewDidLoad];
   
	[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

	[[NSNotificationCenter defaultCenter] addObserver:self
                                 selector:@selector(orientationChanged:)
                                 name:UIDeviceOrientationDidChangeNotification
                                 object:nil];

	[self createGrid];
}

- (void)createGrid
{
	BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIDevice currentDevice].orientation);

	...

	// add a name column
	SDataGridColumn* nameColumn = [[SDataGridColumn alloc] initWithTitle:@"Name 2"];
	// Set the width based on orientation
	nameColumn.width = (isPortrait ? @484 : @600);
	[_shinobiDataGrid addColumn:nameColumn];

	...
}


- (void)orientationChanged:(NSNotification *)notification
{
	[_shinobiDataGrid removeFromSuperview];

	[self createGrid];
}

Wg


#4

One thing I noticed; when you go into landscape, open the overlay menu and select the grid, the view containing the grid resizes to fit inside the main view (minus the width of the overlay) and in turn the grid is created within the bounds of the view.

When you go back into portrait orientation, it looks nasty but if you select the grid again, this time it resizes the view correctly.

Wg


#5

Thank you for your replies!  I tried what you suggested, fiddled around a bit until things worked, then removed code to pair it down to what it actually needs to work.

The slidingView will auto-adjust for device rotation.  The overlay view will auto-adjust for its bounds and frame.  The grid will auto-adjust for its view’s bounds and/or frame.  The key is to set both the bounds and the frame for the view being added to the slidingView.overlay view.  slidingView.overlay.frame will have numbers skewed based on underlay visibility, so use its bounds for the gridViewController view.

In the main ViewController, set both the bounds and frame before adding the subview (in viewDidLoad, the example’s setupSubviews, my underlay button action changeOverlayViewToGrid, wherever needed):

  gridViewController = [[Grid1ViewControlleralloc] init];
 
   gridViewController.view.bounds = slidingView.overlay.bounds;
   gridViewController.view.frame = slidingView.overlay.bounds;
 
   [slidingView.overlayaddSubview:[gridViewControllerview]];

In the gridViewController:

- (void)viewDidLoad

    _shinobiDataGrid.AutoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

#pragma mark - UIViewController methods
// < iOS6
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
   returnYES;
 
}
 
// >= iOS6
- (BOOL)shouldAutorotate {
   returnYES;

}

#6

I haven’t tried to debug it but I can still replicate the issue with the view resizing.

What happens when you rotate to landscape and select the grid button? Doesn’t the view with the grid resize to within the visible area?

Screenshot 1 - Changed to landscape and slid view to see buttons; the width is still the correct size.

Screenshot 2 - Selected Grid 1 and the view (subsequently the grid) resized to just short of the edge of the screen (red line showing).

Screenshot 3 - Sliding the view back over to the left side shows the size of the view isn’t the full width.

Wg


#7

Try this version: rotationProblem_Fixed.zip 

It doesn’t seem to do that anymore, but I might just be missing it.  If you repeat your process several times on the broken version, you can actually get the red-space to take up most of the screen, with the grid mushed into a narrow column.


#8

The reason for Screenshot 2/3 was because I was removing the grid from the superview before creating it again with the new column widths for the new orientation:

- (void)orientationChanged:(NSNotification *)notification
{
	[_shinobiDataGrid removeFromSuperview];

	[self createGrid];
}

The view bounds changed back to the portrait values when the grid was removed from the view. To get around it, I set the frame size of the view when the orientation wasn’t portrait:

- (void)createGrid
{
	BOOL isPortrait = UIInterfaceOrientationIsPortrait([UIDevice currentDevice].orientation);
	
	if (!isPortrait) {
		self.view.frame = CGRectMake(0, 0, 1024, 768);
	}
	
	// create a grid - with a 40 pixel padding
	_shinobiDataGrid = [[ShinobiDataGrid alloc] initWithFrame:CGRectInset(self.view.bounds, 40,40)];
	
	...
}

In the simulator if you go crazy switching orientations, sometimes it’ll get the bounds of the view inbetween the rotation :slight_smile:

Wg


#9

Avoid hard-coded numbers, but yes, I can see where that would work.  I wasn’t rescaling columns - I expect to have enough columns that the grid is always going to need scrolling.  Thank you for looking at the issue; I spent quite a bit of time trying to figure it out before posting.