In my app, I want to set the UIView orientation according to home button orientation of iPhone. I done it using following way:
/* I handled view orientation in shouldAutorotate method*/
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
viewForBarButtons.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
viewForBarButtons.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
else if (interfaceOrientation == UIInterfaceOrientationPortrait)
viewForBarButtons.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin;
else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
viewForBarButtons.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
where viewForBarButtons is a UIView inside a viewController.
But if I set return Yes instead of return (interfaceOrientation == UIInterfaceOrientationPortrait); then it does not work.
How to resolve this issue. If anyone knows it, then please help me.
Similar functionality is implemented in LifeCards app.
Thanks in advance.
The above method is to decide whether to rotate your view to a particular orientation, when device orientation change.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
specifies to support only Portrait orientation.
return YES;
would support all orientation.
But if you are putting your viewcontroller in a TabBarController then it will rotate only if all viewcontrollers support that specific orientation.
Instead of putting the above code to autoresize the object in willRotateToInterfaceOrientation.
But you need know one thing, by specifing
UIViewAutoresizingFlexibleLeftMargin
You are just specifying that view can put as much as space want between object and left margin. But it will keep previous positionson other sides during orientation change, so you might need to phsically change the origin of the object (viewForBarButtons)
Ok. I guess what you are saying is you want the viewForBarButtons beside the homeButton, and need to position/rotate its subviews accordingly.
First register for devie rotaion or use didRotateInterfaceOrientation, to initate rotating subviews of viewForBarButtons.
#define degreesToRadians(x) (M_PI * x / 180.0)
Rotate subviews: replace self with subview object
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (animated)
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
}
if (orientation == UIInterfaceOrientationPortraitUpsideDown)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, degreesToRadians(180));
else if (orientation == UIInterfaceOrientationLandscapeRight)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, degreesToRadians(90));
else if (orientation == UIInterfaceOrientationLandscapeLeft)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, degreesToRadians(-90));
else
self.transform=CGAffineTransformIdentity;
if (animated)
[UIView commitAnimations];
Related
I searched every where but not find the solution of this I am New in iphone.In every where I got the set the height of navigation or my view is not rotating in orientation like issue.my view is rotating but my navigation bar is on same position please some one help me if You have solution.Thanks I have show my some code in down which I used for Orientation.when I tap on my tab bar my simulator is automatic rotate and I want tab bar also rotate but using this code only simulator is rotate not tab bar and navigation bar and sorry for my bad english.
CGAffineTransform transform = CGAffineTransformIdentity;
switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
transform = CGAffineTransformMakeRotation(M_PI_2);
break;
default:
break;
}
[[UIApplication sharedApplication]setStatusBarOrientation:UIInterfaceOrientationPortrait];
[UIView animateWithDuration:0.2f animations:^ {
[self.navigationController.view setTransform:transform];
}];
[self.view setFrame:CGRectMake(0, 0, 320, 480)];
[self.view setNeedsLayout];
This code is, no offense intended, very curious. I'm not sure what you are trying to do. What problem are you trying to solve? Playing around with CGAffineTransform's can definitely generate strange results like what you describe if you're not very careful.
If you just want to make sure that your app successfully supports landscape and portrait orientations, you can implement shouldAutorotateToInterfaceOrientation in your view controller. When you do this, all of the various controls will reorient themselves accordingly.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Support all orientations on iPad
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return YES;
// otherwise, for iPhone, support portrait and landscape left and right
return ((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
But if I have misunderstood what you're trying to do, i.e., you're trying to do something more sophisticated than just supporting both landscape and portrait orientation, let me know.
I apologize because I don't remember where I originally got this code (but it's referenced in SO here), but the following can be used to force landscape orientation:
First, make sure that your shouldAutoRotateToInterfaceOrientation should read as follows:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight))
return YES;
else
return NO;
}
Second, in viewDidLoad, add the following code:
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
}
For some reason, removing the view from the main window and then re-adding it forces it to query shouldAutorotateToInterfaceOrientation and set the orientation correctly. Given that this isn't an Apple approved approach, maybe one should refrain from using it, but it works for me. Your mileage may vary. But that SO discussion also refers to other techniques, too.
I am working on a project where I have added UIWebviews in the UIscrollview to show the description. I did this because I want to add the swipe effect to move to the new description page. Now, I want to resize that UIscrollview and its content (i.e uiwebview) when the orientation changes (i.e portrait to landscape or Viceversa).
Please give me any sample code or any suggestions for it.
To resize the webview you have to write:-
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
webview.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * someValue1,
scrollView.frame.size.height * someValue2);
}
You can put your code in the following code block :
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ([self isPadPortrait]) {
// Your code for Portrait
// set frame here
} else if ([self isPadLandscape]) {
// Your code for Landscape
// set frame here
}
and following code will take care of orientation change :
- (BOOL)isPadPortrait
{
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
&& (self.interfaceOrientation == UIInterfaceOrientationPortrait
|| self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown));
}
- (BOOL)isPadLandscape
{
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
&& (self.interfaceOrientation == UIInterfaceOrientationLandscapeRight
|| self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft));
}
You can set the autoresizingMask of scrollView and add this code to your .m file according to your requirement.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * someValue1,
scrollView.frame.size.height * someValue2);
}
Here is a link to a similar question and their solution:
Scale image to fit screen on iPhone rotation
They used a combination of AutoresizingMasks and ContentModes for both the ScrollView and, in their case, an ImageView, although I imagine the same solution would work for your WebView.
when ever the orientation changed
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
// this delegate method will called if we set should auto orientation return yes;
when ever we changed orientation so set frames..
}
for example
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
appDelegate.interface=interfaceOrientation;
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
// SET FRAMES FOR LANDSCAPE HERE
}
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation == UIInterfaceOrientationPortrait)
{
//SET FRAMES FOR Portrait HERE
}
}
I have a view controller in my iphone app setup so that when I change the orientation from portrait to landscape, I change the view. When I change the orientation back from landscape to portrait, the initial view comes back, except this time it is all crammed into the left hand side of the screen. Eventually, when I change orientations enough times everything disappears completely. Is this a common issue beginners have? What could I be doing wrong?
In my root controller I am allowing the orientation to change only when a specific view is being shown with this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if (self.currentView == (NSInteger*)Chart || self.currentView == (NSInteger*)Detail) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
return (interfaceOrientation == UIInterfaceOrientationPortrait);
Where self.currentView is an enum of what view I currently have up. The Detail view I want to make sure stays as a portrait view, but when I change the orientation while on that view I want it to change the view to the Graph. Again, this works fine the first time, but when I change back from Graph to Detail, it crams all the controls on the Detail view to the left hand side of the screen.
Here is how I'm changing the view:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if (self.currentView == (NSInteger*)Detail && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeView" object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:Chart] forKey:#"view"]];
}
if (self.currentView == (NSInteger*)Chart && (toInterfaceOrientation == UIInterfaceOrientationPortrait)) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeView" object:self userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:Detail] forKey:#"view"]];
}
#justin I once did this which got me into same situation as you are. May be you can check if you haven't done something like this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
CGRect rect;
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
rect = CGRectMake(tableView.frame.origin.x,tableView.frame.origin.y,
tableView.frame.size.width - 50, tableView.frame.size.height - 30);
}
else {
rect = CGRectMake(tableView.frame.origin.x,aBar.frame.origin.y,
tableView.frame.size.width, tableView.frame.size.height);
}
[tableView setFrame:rect];
return YES;
}
All I wanted was a table view with small frame in Portrait mode, without saving the original Frame I was trying to reduce its width and height which eventually brought the table view to a very small size after multiple rotation..
Lolzzz. I should have first saved the original tableview frame and then done something like this
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
tableView.frame = CGRectMake(tableView.frame.origin.x,tableView.frame.origin.y,
tableView.frame.size.width - 50, tableView.frame.size.height - 30);
}
else {
tableView.frame = originalTableViewFrame;
}
check if you have autoresizeSubviews ON (in XIB/Inteface Builder) on your view and possibly parent views and try to turn it off if you are changing frame manually , this solved it for my case
My landscape subview is being cut off by the previous view, why is it like that?
Cut off as in the previous view is at the bottom part around 1/3 quarter of the screen even when the new subview is added. Something like this > http://i41.photobucket.com/albums/e253/welzenn99/123.png
you need to set that view's frame in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
OR in
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
in the method where you tell the subview to come out ([self.view addSubview:someView.view];) add
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight)) {
//rotate to landscape
someView.view.frame = CGRectMake(0,0,480,320);
}
else if (orientation == UIDeviceOrientationPortrait) {
//rotate to portrait
isomeView.view.frame = CGRectMake(0,0,320,480);
}
worked for me. good luck
I have a simple UIViewController that uses a XIB for its interface.
As such, the interface simply comprises a UIView, a UIActivityIndicator and a UILabel. I have the sizing constraints in Interface Builder set to keep the activity indicator and the label centred when the view rotates.
The UIViewController is set to return YES for portrait and landscape orientations in the -shouldAutorotateToInterfaceOrientation: method.
The view is added to the view hierarchy manually, using
if (!activityOverlay)
activityOverlay = [[XBActivityOverlayViewController alloc] initWithNibName:#"XBActivityOverlayViewController" bundle:nil message:#"Connecting..."];
[activityOverlay.view setAlpha:0.0f];
[self.window addSubview:activityOverlay.view];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3f];
[activityOverlay.view setAlpha:0.9f];
[UIView commitAnimations];
The problem I'm having is that if the device is already in landscape orientation and the view is added to the hierarchy at this point, the view is still in portrait orientation, and doesn't auto rotate.
What do I need to do to add the view in the same orientation as the parent view?
I do not know if it is the right answer to your question but I hope can help:
For me, every time I add/dismiss a modal or display a new view, the following function is called:
-(void) detectOrientation
{
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight))
{
item1.frame = CGRectMake(147.0, 241.0, 56.0, 28.0);
item2.frame = CGRectMake(265.0, 241.0, 56.0, 28.0);
}
else if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) || !inLandscapeOrientation)
{
item1.frame = CGRectMake(35.0, 425.0, 35.0, 28.0);
item2.frame = CGRectMake(176.0, 425.0, 35.0, 28.0);
}
}
Here I change the position according to the current device orientation. Maybe if you detect that the current orientation is landscape you add a subview that has such orientation.
Alejandra :)