SkylarEC
09-05-2008, 08:27 PM
Alright, it seems that very few people know how to make an application detect the Orientation of the device, and to redraw its views to the correct size. So, I whipped up this app right quickly for youse guys.

Working Application w/SourceCode after the posted source code. This build assumes that you are a registered developer with Apple and have access to the SDK. This should work in xcode, but will also work on the toolchain, presuming you have patched your headers appropriately.

main.m
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import "HelloRotation.h"

int main(int argc, char **argv){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retValue = UIApplicationMain(argc, argv, @"HelloRotation", @"HelloRotation");
[pool release];
return retValue;
}

HelloRotation.h
#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#import <GraphicsServices/GraphicsServices.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIScreen.h>
#import <UIKit/UITouch.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <strings.h>

#include "HRViewController.h"

@class UIEvent;


@interface HelloRotation : UIApplication {

UIWindow *window;
HRViewController *hrViewController;
}

@end

HelloRotation.m
#import "HelloRotation.h"

@implementation HelloRotation


-(void)applicationDidFinishLaunching:(NSNotificatio n *)aNotification {

struct CGRect rect = [[UIScreen mainScreen] bounds];
rect.origin.x = rect.origin.y = 0.0f;

hrViewController = [[HRViewController alloc] initWithFrame:rect];

window = [[UIWindow alloc] initWithFrame:rect];
[window makeKeyAndVisible];
[window setContentView:hrViewController.view];
}

-(void)dealloc {
[window dealloc];
[hrViewController dealloc];
[super dealloc];
}

@end

HRViewController.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIColor.h>
#import <UIKit/UIScreen.h>
#import <UIKit/UIView.h>
#import <UIKit/UIViewController.h>

@interface HRViewController : UIViewController {
struct CGRect rect;
UIView *backView;
UIImageView *imageView;
}

@property (nonatomic, retain) UIImageView *imageView;

-(id)initWithFrame:(CGRect)_rect;

@end

HRViewController.m
#include "HRViewController.h"

@implementation HRViewController

@synthesize imageView;


//UIViewControllers are full screen. I have added the initWithFrame because I want to pass the appFrame down
//to the subviews and methods. It's not important to do this. init would have sufficed just fine.

-(id)initWithFrame:(CGRect)_rect {
rect = _rect;
if (self = [super init]) {
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"105.png"]];
imageView.alpha = 0.0;
[imageView setFrame:rect];

backView = [[UIView alloc] initWithFrame:rect];
backView.backgroundColor = [UIColor blackColor];

return self;
}
}

- (void)loadView {
self.view = [[UIView alloc] initWithFrame:rect];
self.view.backgroundColor = [UIColor blackColor];
[self.view addSubview:backView];
}

-(void)viewDidLoad{ //This is not necessary, but I hate Apps that just POP onto the screen
[UIView beginAnimations:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:0.50];
[self.view addSubview:self.imageView];
self.imageView.alpha = 1.0;
[UIView endAnimations];
}

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIIn terfaceOrientation)interfaceOrientation {
return YES;
}

-(void)didRotateFromInterfaceOrientation:(UIInterfa ceOrientation)fromInterfaceOrientation {
if((self.interfaceOrientation == UIDeviceOrientationLandscapeLeft) || (self.interfaceOrientation == UIDeviceOrientationLandscapeRight)){
float newWidth = rect.size.width *0.66f;
[UIView beginAnimations:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.50];
[self.imageView setFrame:CGRectMake(rect.size.height / 2 - newWidth / 2, 0, newWidth, rect.size.width)];
[UIView endAnimations];
} else if((self.interfaceOrientation == UIDeviceOrientationPortrait) || (self.interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)){
[UIView beginAnimations:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.50];
[self.imageView setFrame:rect];
[UIView endAnimations];
}
}


-(void)dealloc {
[backView dealloc];
[imageView dealloc];
[super dealloc];
}

@end



To get a feel for the Application, please run it first, then mess around with it. Obviously, if you want the landscape view to fill the screen, just set its frame to (0,0, rect.size.height, rect.size.width)
http://www.touchrepo.com/SampleCode/HelloRotation.app.7z

Tom_fn
09-05-2008, 08:28 PM
Thanks for the guide skylar!

BroadStBullies
09-05-2008, 08:50 PM
Cool. I saw your video of this on youtube.

gojohnnyboi
09-05-2008, 09:14 PM
yeah resetting the frame of the views would be the easy way to do this. now i have the sdk which is making this a little easier for me :)

SkylarEC
09-05-2008, 10:11 PM
yeah resetting the frame of the views would be the easy way to do this. now i have the sdk which is making this a little easier for me :)

That's all Apple does. Watch Safari. Watch Photos. the only thing Apple does different in their Photos app that this demo does is that it pins the image to its center and only resizes. This demo doesn't pin it down, although you could easily modify the code to do that. I wanted to show you three simultaneous animations instead of two.

Just for the common knowledge, animations are performed in a separate thread automatically, so they shouldn't effect your apps all that much.


You can expand from this very easy by adding: [UIView setTransform:CGAffineTransformwhatever]

HITMAN45, that example you saw on YouTube is an example of what not to do. It is not this app at all.

BroadStBullies
09-05-2008, 10:28 PM
HITMAN45, that example you saw on YouTube is an example of what not to do. It is not this app at all.

Oh. my bad.