enter image description herehai, i have a list of buttons in a view which is a sub view of another UIView. i need to rearrange these buttons in order while the device orientation changes to landscape mode.
is their any way to do this? or else i need to do all these things manually by repositioning all buttons?
shouldAutorotateToInterfaceOrientation:, mentioned in the other answers, is for letting your view controller decide whether or not to allow autorotation to a given orientation. (you're supposed to return YES or NO).
If you really want to programmatically adjust layout of your subviews, you would do it in either
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[UIView animateWithDuration: duration
delay: 0.0f
options: UIViewAnimationOptionCurveLinear
animations: ^(void) {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
self.button.frame = CGRectMake(x1, y1, self.button.frame.size.width, self.button.frame.size.height);
} else {
self.button.frame = CGRectMake(x2, y2, self.button.frame.size.width, self.button.frame.size.height);
}
}
completion: ^(BOOL finished) {
// code to run after animation completes can go here
}];
}
or, you can use willAnimateRotationToInterfaceOrientation:duration: for one-step rotations.
Not only is it only called when the autorotation actually happens, but it gives you the duration of the animation. This allows you to wrap any animatable view property changes inside your own animation, so that they smoothly animate during the rotation, instead of just snapping to their new values.
But, really, this is usually not the best way to solve the problem. See this link for a more general discussion of the issue
Change the CGFrame of you buttons in the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation==UIInterFaceOrientationPortrait)
{
Button1.frame=...;
Button2.frame=....;
}
else if(interfaceOrientation==UIInterFaceOrientationLandscapeLeft)
{
Button1.frame=...;
Button2.frame=....;
}
return YES;
}
1-you can use this
YOUR_OBJECT.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin;
OR
2- use frame property with CGRectMake for your object in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
if(interfaceOrientation==UIInterFaceOrientationPortrait)
else if(interfaceOrientation==UIInterFaceOrientationLandscapeLeft)
You can handle it via
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
method.
Make two methods in your viewController.h class assume they are -
-(void)viewForPortraitMode;
-(void)viewForLandscapeMode;
And this is the body part of both in your viewcontroller.m file.
//Set frame according to you
-(void)viewForPortraitMode
{
[btn1 setFrame:CGRectMake(117.0, 383.0, 87.0, 37.0)];
[btn2 setFrame:CGRectMake(40.0, 20.0, 240.0, 324.0)];
}
-(void)viewForLandscapeMode
{
[btn1 setFrame:CGRectMake(200.0, 252, 87.0, 37.0)];
[btn2 setFrame:CGRectMake(20.0, 7.0, 446.0, 228.0)];
}
And call these two methods in this
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
[self viewForPortraitMode];
}
else
{
[self viewForLandscapeMode];
}
return YES;
}
Related
I am brand new to iOS development, and I am trying to implement a rotatable and resizable user interface. The problem that I am encountering is re-setting the position of UI elements upon rotation. I can't even get the simple code below to work properly:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.button.frame = CGRectMake(502.0, 207.0, 73.0, 44.0);
} else {
self.button.frame = CGRectMake(197.0, 69.0, 73.0, 44.0);
}
}
I have de-selected the Autoresize Subviews option; however, the button still ends up in the same spot. I have logged the frame position, which appears to have the correct coordinates, but it is definitely not ending up that way.
in the first panel of Utility inspect. uncheck the use auto-layout.
How can I write my code which supports both landscape and portrait? I tried this one -
(void)setupForOrientation:(UIInterfaceOrientation)orientation {
if (UIInterfaceOrientationIsPortrait(orientation)) {
CGRect bounds = CGRectMake(0, 0, 768, 1004);
scrollView.frame = bounds;
// Other view positioning for portrait.
} else {
CGRect bounds = CGRectMake(0, 0, 1024, 748);
scrollView.frame = bounds;
// Other view positioning for landscape.
}
[self drawBackgroundForOrientation:orientation];
}
But its not working. Please help me.
Use this code:
- (void)viewDidLoad
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
}
- (void) orientationChanged:(id)object
{
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft || [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight )
{
self.view=self.landscapeView;
NSLog(#"ViewwillAppear= Land");
}
else
{
self.view = self.portraitView;
NSLog(#"ViewwillAppear= Port");
}
You'll always have to return yes for this function whenever you require orientation support.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
Edit 1: P.S. I've taken portraitView & landscapeView as two separate UIViews.
I think you want to override the shouldAutorotateToInterfaceOrientation: method of your main view controller to always return YES. That or you can specify the supported orientations for your app in the app properties.
You have to use following method to support both orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
//this method will call just before changing Orientation of device you can set frames in this method
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
}
If you have used viewcontrollers then there are a few methods that you can override. The first being
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation; // Override to allow rotation. Default returns YES only for UIInterfaceOrientationPortrait
Where you can specify whether a particular view will support rotation or not.
If you need to configure your views manually according to the orientation you can override the following methods
As per the documentation
Your implementation of this method should simply return YES or NO based on the value in the interfaceOrientation parameter. Do not attempt to get the value of the interfaceOrientation property or check the orientation value reported by the UIDevice class. Your view controller is either capable of supporting a given orientation or it is not.
// Notifies when rotation begins, reaches halfway point and ends.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
AND
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
To achieve what you wish to implement you can return YES for supported orientation and then use the second method to configure your view accordingly by calling [self setupForOrientation:orientation];
Hope it helps!!!
Here is my code to set at the center
UIButton *videoImage = [[UIButton alloc]initWithFrame:CGRectMake((secondImageView.frame.size.width/2)-50,(secondImageView.frame.size.height/2)-50,50,50)];
videoImage.transform = CGAffineTransformMakeRotation(ang*(3.14/180));
[videoImage setBackgroundImage:[UIImage imageNamed:#"PlayButton.png"] forState:UIControlStateNormal];
[videoImage addTarget:self action:#selector(PlayMusicOnClickofButton:) forControlEvents:UIControlEventTouchUpInside];
[secondImageView addSubview:videoImage];
videoImage.tag = k+1000;
secondImageView.userInteractionEnabled = YES;
[videoImage release];
The problem that i am facing is when i change orientation of button it's position gets changed. It doesn't remain at center. Please help
Thanks
Actually you should use this method....
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
//handle how you want to show in landscape mode
}
else
{
//handle how you want to show in portrait mode
}
return YES;
}
You need to handle this. What you are doing is correct. You need to do tweak it when the orientation changes as the dimensions of your parent view change. Implement willAnimateRotationToInterfaceOrientation delegate. check this out -
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft||toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
//handle how you want to show in landscape mode
}
else
{
//handle how you want to show in portrait mode
}
}
I have a UITableView being shown in a popover. One cell in my table view has a UITextField in it. When the text field is being edited (the keyboard is visible) and I rotate the device from portrait to landscape and then try to scroll the table view, it keeps going past its bounds, instead of stopping and "bouncing".
Does anyone know how to fix this?
You can try to detect when the device is rotated and call the tableViewController method that adjusts scrolling position of selected cell to the area you need.
You can use following code when rotate device
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if ([appDelegate.aPopover isPopoverVisible])
{
[appDelegate.aPopover dismissPopoverAnimated:NO];
CGSize size = [self rotatedSize];
size.height -= [[self.view viewWithTag:154] frame].size.height;
appDelegate.aPopover.popoverContentSize = size;
[appDelegate.aPopover presentPopoverFromRect:[[self.view viewWithTag:154] frame]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionDown
animated:YES];
}
}
// for set popoverview size when rotate screen
-(CGSize)rotatedSize
{
UIDeviceOrientation orientation1 = [[UIDevice currentDevice] orientation];
UIInterfaceOrientation toInterfaceOrientation = orientation1;
if ((toInterfaceOrientation == UIInterfaceOrientationPortrait) || (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
{
return self.view.frame.size;
}
else
{
return CGSizeMake(self.view.frame.size.height, self.view.frame.size.width);
}
}
Thank you,
I'm having a real issue with UITabBarController.
The outcome I'm after is the following:
1) in portrait mode, a simple tab bar based application (with navigation bars) nothing too fancy.
2) in landscape mode, I want to use my own UIViewController ignoring the UITabBar completely.
The approach (I tried many variants) I tried last which I fail to understand why is not "working" is the following:
I have a custom UIViewController (Call this AA) that is suppose to manage "everything".
This controller is added to the window in application start and in its loadView creates two controllers: a UITabBarController (Call this TBC) and a UILandscapeController (Call this LSC). then I add the tabbarcontroller view as a subview of AA's view.
now in AA class I override the didRotate blah or willRotate blah and basically want to switch between the two views, by this I means something like: (pseudo code):
going from portrait to landscape:
[TBC.view removeFromSuperView];
[AA.view addSubview:LSC.view];
and when returning to portrait reverse it.
[LSC.view removeFromSuperView];
[AA.view addSubview:TBC.view];
The amount of problems I have (well, it simple rotates wrongly creating a real messed up interface) are something completely unexplained. It seems like the tabbarcontroller view does not "like" at all to be in the standard view heirarchy but rather it wants to be attached directly to the screen.
I wonder what is the best approach to achieve my goal and why the tabbar does not like to be a subview of a view,
any hints mostly appreciated.
-t
Just in case you still need the answer, or someone else stumbles onto this, I've done the same thing and got it working, but there are a couple of hoops you have to jump through. In order to rotate a UITabBarController's view, there are four things you have to do:
Remove the status bar before switching to the view
Rotate the view to the new frame
Add the status bar back to the view
Switch to the view.
I've got a RootRotationController that does this that looks like this:
#implementation RootRotationController
#define degreesToRadian(x) (M_PI * (x) / 180.0)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if ((UIInterfaceOrientationPortrait == interfaceOrientation) || (UIInterfaceOrientationPortraitUpsideDown == interfaceOrientation)) {
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
}
// Return YES for supported orientations
return YES;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
[super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration];
if (UIInterfaceOrientationLandscapeLeft == interfaceOrientation) {
self.view = self.landscape.view;
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(-90));
self.view.bounds = CGRectMake(0, 0, 480, 300);
} else if (UIInterfaceOrientationLandscapeRight == interfaceOrientation) {
self.view = self.landscape.view;
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
self.view.bounds = CGRectMake(0, 0, 480, 300);
} else if (UIInterfaceOrientationPortrait == interfaceOrientation) {
mainInterface.view.transform = CGAffineTransformIdentity;
mainInterface.view.transform = CGAffineTransformMakeRotation(degreesToRadian(0));
mainInterface.view.bounds = CGRectMake(0, 0, 300, 480);
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
self.view = mainInterface.view;
} else if (UIInterfaceOrientationPortraitUpsideDown == interfaceOrientation) {
mainInterface.view.transform = CGAffineTransformIdentity;
mainInterface.view.transform = CGAffineTransformMakeRotation(degreesToRadian(180));
mainInterface.view.bounds = CGRectMake(0, 0, 300,480);
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
self.view = mainInterface.view;
}
}
In addition, you should know that shouldAutorotateToInterfaceOrientation is called just after adding the root controller's view to the window, so you'll have to re-enable the status bar just after having done so in your application delegate.
Your problem comes from the typo, I think. Change removeFromSuperView to removeFromSuperview.
Though, it still has a problem. Tab bar doesn't rotate properly. It go upwards till it disappers.
How about not removing the tab bar, and make it transparent.
Check out the UIViewController instance method rotatingFooterView in the docs.
Or, you may manage TabBar by yourself, not through the UITabBarController.