UIView rotation text manipulation - ios

I have a view that consists of a bunch of UILabels. As of right now the view is only configured to work when the device's orientation is portrait, however I would like to make it so that when the device is rotated one specific UILabel's location is changed and text size is magnified. When the device's orientation is reverted to portrait, I'd like for it to return to its original state.
How should I go about doing this?

Implement this method in your ViewController and do the changes accordingly.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
// do something in landscape orientation
} else {
// do something in portrait orientation
}
}

Related

Different portrait and landscape autolayout constraints: where to set them when the device is firstly in landscape?

I have set the NSLayoutConstraint as IBOutlet, and the values I've set in the storyboard and IB is for portrait orientation. When I run the app in portrait orientation and then I rotate the device to landscape, I manage the constraints updates. But when I run the app being the device already in landscape, the constraints have the values for portrait.
Where should I check the current orientation of the device when the view controller is loaded and the view shown, and set the appropriate constraints according to such orientation?
Thanks
you can initially keep a condition in viewDidLoad method
if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){
// Apply Portrait Constraints
}
else{
// Apply Landscape Constraints
}
later when the user changes orientation you can check in below method and apply the same condition
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
// Apply Portrait Constraints
}
else{
// Apply Landscape Constraints
}
}

Calling viewWillTransitionToSize: manually

I currently have a UiViewController called Page2
Now if the orientation of the Iphone is changed to landscape the following method is called which is well and good
-(void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
/*The orientation of the phone just changed*/
}
Now My issue is that if the user is already in landscape mode in ViewController page1 and goes to UIViewController Page2 the above method is not called. I know I can check the current orientation of the phone using the following code
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == UIInterfaceOrientationLandscapeLeft)
{
//Its in landscape mode
}
However I do not know what parameters to pass for size to the method (that gets called automatically only when the orientation changes) I would like to call this method manually if I detect its in landscape mode. Any suggestions on how to obtain the current size to pass to the method below in which the width would be greater than the height (since its in landscape mode)
-(void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator ;
I tried doing this
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
[self viewWillTransitionToSize:self.view.frame.size withTransitionCoordinator:nil];
}
However the height was greater than the width indicating it was still in portrait mode ... What am i doing wrong ? How can I call this method manually and pass the current size in which width is greater than the height ?
Update:
I would like to give a little more background. I currently have two UIViewControllers PageOne and PageTwo. Now PageTwo has something like this in it for orientation control. The control flow goes from PageOne to PageTwo
//When device rotates
-(void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
DKTuner* sensitivityTuner;
if (size.width > size.height)
{ //Yes this is the landscape mode - Realign some controls to a different position.
.....
}
else
{
// this is portrait mode
.....
}
}
Now the logic of my code in PageTwo assumes that the user entered it in Portrait Mode. However in reality that will not always be true because the user could enter pageTwo while in LandscapeMode. In that case the controls dont readjust to landscape mode as the method of reorientation does not get called in pageTwo. My question is how can I call the reorientation method viewWillTransitionToSize manually and pass a size parameter in which the size width is greater than the height ?
Whatever you're doing in viewWillTransitionToSize:withTransitionCoordinator:, you should probably do in viewWillLayoutSubviews or viewDidLayoutSubviews instead. Those are sent both on a rotation and when the view controller's view first comes onto the screen, and UIKit updates the view's frame before calling viewWillLayoutSubviews.

Preferred way to set frame at run time for different orientation

I have two different UI specs for my iOS app.
I'm facing issues in orientation change(Upsidedown not supporting) for following scenario.FYI :I'm using using self.view.frame.size.width to set width for UI and to identify orientation change i'm using UIDeviceOrientationDidChangeNotification1.Change orientation to landscape
2.change to orientation upsidedown (not settign any frame)
3.change orientation to portrait directly (setting frame for portrait mode)
On following these steps my UI frame is getting misplaced.I'm getting width as 568 for portrait mode.
Please suggest me a better way to fix this problem.
It is not good practice to change the self.view frame when rotating because its bound are handled by the UIViewController rotation logic.
You can use the willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: delegate methods for manual rotation.
you are listing to your device orientation changes and you need to allow UI rotation and listen to it with
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
//update your view's subviews
}
note that UIDeviceOrientation is different from UIInterfaceOrientation
to allow interface rotation add this to the view controller and make sure that in the project plist you are supporting the landscape and portrait in the 'Supported interface orientations' key
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}

shouldAutorotate is not locking the screen orientation

I ma trying to lock screen orientation to only landscape orientation when a certain image is still visible, then when the image is hidden, unlock all orientations (targeting iOS 6):
-(BOOL)shouldAutorotate{
if (self.splashImageView.hidden == NO) {
return UIInterfaceOrientationMaskPortrait;//gets called when image is visible
}else{
return UIInterfaceOrientationMaskAll;//gets called when image is hidden
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self shouldAutorotate];
}
As you may notice, shouldAutorotate is called properly but the screen is always supporting landscape orientation even when the image is still visible, is there something missing?
P.S: Please note I am trying to get that to work on a tabbar view controller (a UIViewController subclass).
In your appdelegate you have those two methods.but do you have setting like in your project settings -> go to summary tab and see if orientation is set to only landscape or all.Just try to set those.

call shouldAutorotateToInterfaceOrientation but lock view from rotating

I want to create a UIVIew that will not rotate when I will call to shouldAutorotateToInterfaceOrientation , and other subviews will rotate.
and i want to keep the shouldAutorotateToInterfaceOrientation suppot, and not use notification.
thanks
Be sure to define exactly what you mean by having a view "not rotate" when the device is rotated. Rotation can mean several things, depending on which coordinate system to which you refer. A better way to think about it is simply, what do you want your view to look like for each device orientation.
Just to remind, shouldAutorotateTo... is sent to your view controller by the system. You don't invoke it yourself. It doesn't cause rotation. It lets the system ask your view controller what orientations it supports.
Your VC should answer YES for all orientations it supports. A supported orientation is one where the view changes layout in response to a device orientation change, so if any layout change occurs for a given orientation, then the answer to shouldAutorotateTo is probably YES.
Altering subview layout for a given interface orientation is mostly your responsibility. Views have an autoresizingMask which is a bit vector describing some options for sizing and positioning relative to their parent, and this is often adequate. The way to fully control layout on orientation change is by implementing willAnimateRotationToInterfaceOrientation.
For example, here's a fairly permissive shouldAutorotate, enabling all but one orientation...
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And here's how you would control how subviews layout on rotation...
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
UIView *testView = [self.view viewWithTag:16];
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
// change frames here to make the ui appear according to your spec
// including however you define "not rotating" for each view
self.subviewA.frame = .....
self.subviewB.frame = .....
} else {
self.subviewA.frame = .....
self.subviewB.frame = .....
}
}
If you want one UIView not to Rotate with orientation, one of the easy solution is to add that view to Application top Window like this. Because window dont rotate with device orientations.
[[[[UIApplication sharedApplication]windows]objectAtIndex:0]addSubview:customView];

Resources