transitionWithView animation for LandsCape view is weird? - ios

For All ViewControllers in my application I used Landscape mode ie I have Changed the Orientation option to LandScape in the Inspector Pane for the UIView of the ViewController in xib. I used the animation mentioned here.
As I don't want to keep many View Controllers in memory, while showing next ViewController I use to load them as rootViewController of the application key window
[UIView transitionWithView:self.window
duration:0.8
options:UIViewAnimationOptionTransitionFlipFromTop//But rotating left to roght in portrait mode
animations:^{
self.window.rootViewController = currentView;
}
completion:nil];
My problem is that during the animation phase Instead of animating in the landscape mode, the View is animated in portrait mode after the animation ends the View comes to the LanscapeMode,

Related

Add UIView in Landscape mode

I need to add the ads functionality in my iOS App. And ads screen would appear after some time interval. My whole is in Landscape mode only. When I tried to add the view on current view then it shows the views in portrait mode not in landscape mode. I have set the view frame i.e. CGSizeMake(0,0, 568, 320)
time = [NSTimer scheduledTimerWithTimeInterval:2.0f
target:self
selector:#selector(showfirstad)
userInfo:nil
repeats:YES];
-(void)showfirstad {
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:firstad];
}
It appears like this .
_window = [UIApplication sharedApplication].keyWindow;
if (!_window) _window = [[UIApplication sharedApplication].windows objectAtIndex:0];
UIInterfaceOrientation orientation = self.window.rootViewController.interfaceOrientation;
// Set appropriate view frame (it won't be autosized by addSubview:)
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
if (UIInterfaceOrientationIsLandscape(orientation))
{
// Need to flip the X-Y coordinates for landscape
self.view_login.frame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width+20);
else
{
self.view_login.frame = appFrame;
}
[[[_window subviews] objectAtIndex:0] addSubview:self.view_login];
The reason your UIView gets displayed in portrait orientation while the rest of your app gets displayed in landscape is because you are adding the UIView as a subview of your window rather than adding it as a subview of a view controller's view. This places it outside of the view hierarchy that gets transformed automatically through autorotation.
The app's window object coordinates autorotation by finding its topmost subview that has a corresponding view controller. Upon device rotation, the window calls shouldAutorotateToInterfaceOrientation: on this view controller and transforms its view as appropriate. If you want your view to autorotate, it must be a part of this view's hierarchy.
So instead of [window addSubview:UIView];, do something like [self.view addSubview:UIView];
I had the same issues with rotation and autolayots when used addSubview:myView.
I managed to solve this problem by using standard container controllers or placing views directly to storyboard.
You can probably just add the view that will keep your ad into the screen in storyboard and then set hidden property to YES. Then you can change it to YES after some time.

Place a UIView on top of a UINavigationcontroller in landscape mode

what would be the best way to show a UIView on top of a UINavigationController when in landscape mode?
Trying
[self.navigationController.view addSubView: myView]
places myView under the Navigationbar.
[self.window addSubView: myView]
will show myView in portrait orientation (i.e. 90 degrees rotated to the left or right). I could rotate, but I hope there is a better solution.
Is there any way to cover the entire NavigationController with a UIView?
Maybe you can just hide the navigation bar of the Navigation Controller ?
Like this : self.navigationController.navigationBarHidden = YES
You can implement the following.
You only want the view to be there in landscape mode. So, you should do the following pice of code in
didRotateToInterfaceOrientation: method, hide the view when it rotates to potrait mode and show it when it rotates in landscape mode.
Hope this helps.
My solution was to add the view to UIWindow and rotate it depending on the current orientation.

Landscape xib appears as portrait

I have a view controller and separate nib files for portrait and landscape. On rotating, I load the respective nib. The methods
shouldAutorotateToInterfaceOrientation and willRotateToInterfaceOrientation
get called and the nib does change.
The problem:
the landscape nib does not appear as landscape, but portrait! The status bar is
correctly rotated and appears on the top:
(Sorry, couldn't paste the image, because my account is new. The screenshot is in
landscape, with a landscape status bar, but a landscape view shown as portrait.)
One would think the problem lies in not setting the orientation as Landscape in IB Simulated metrics for the view, but I've done that and the view appears as landscape in IB. (I don't think it would even be possible to create a rotated button like that if the view was portrait.) Besides these two nibs I have a mainwindow.xib, which contains the app delegate, window and view controller objects.
EDIT: I realized that the views are actually rotating, when they should "stay up". It's like there's an extra transformation. When I rotate the phone 90° right, the landscape xib is displayed rotated 90° right. When I rotate the phone another 90° right, the portrait xib is displayed upside down. The status bar is always correctly displayed at the top.
EDIT2: Using
self.view.transform = CGAffineTransformMakeRotation((M_PI * (90) / 180.0));
in willRotateToInterfaceOrientation I can rotate the view to landscape left (and to any orientation I want), so I can use that as a workaround. However, I have other projects, where the view rotates automatically and doesn't require the use of CGAffineTransformMakeRotation. It's like something is preventing the automatic rotation here.
Are you adding the view loaded from nib as subView? If Only the status bar is rotating it means your previous view is hung while releasing the view and adding the new view.Can you tell how are you adding the view loaded from xib to the SuperView.
Make sure you are releasing the previous view correctly while loading the other view,put NSLOG in dealloc of the views and check whether the view is getting released completely.
I had done something similar to this only instead of making an nib file separately I just added two subviews to the main nib as prtraitView and Landscape View
and switched them as follows
In viewDidAppear method
-(void)viewDidAppear:(BOOL)animated{
if(UIDeviceOrientationIsPortrait(self.interfaceOrientation))
{
self.portraitVIew.frame=self.view.bounds;
self.portraitVIew.frame=self.view.frame;
[self.view addSubview:self.portraitVIew];
}else{
self.landscapeView.frame=self.view.frame;
[self.view addSubview:self.landscapeView];
}
self.view.autoresizesSubviews = YES;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(deviceOrientationDidChangeNotification:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
and then Implemented deviceOrientationDidChangeNotification as follows
- (void)deviceOrientationDidChangeNotification:(NSNotification*)note
{
if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad) {
}else{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
self.landscapeView.hidden=NO;
self.landscapeView.frame=self.view.frame;
[self.portraitVIew removeFromSuperview];
[self.view addSubview:self.landscapeView];
}else {
self.landscapeView.hidden=YES;
self.portraitVIew.frame=self.view.frame;
NSLog(#"Portrait");
[self.view addSubview:self.portraitVIew];
}
}
}
It worked very well for me..

iOS - Portrait Locked Tab Controller App Won't Allow Landscaped Movie Player

I have an app that is purely a Tab Bar Controller with 5 tabs (views). I want those views to be portrait only. However, the app does allow video clips to be played and uses an MPMoviePlayerViewController to do so. But I can't get the player to rotate to landscape!
I have tried the following (along with a lot of other things):
Subclassing MPMoviePlayerViewController and overriding the shouldAutorotateToInterfaceOrientation method for that class.
Allowing the app to have landscape orientation, then attempt to lock the tab views to portrait (doesn't lock them, allows them to go to landscape which I don't want).
I have scoured StackOverflow and Google for days now!
Anyone familiar with this issue and how to get the movie player to rotate???
try implementing UIViewController containment. Designate the viewController of the tab that you are showing the movie in as the parent (or container) viewController.
You will want to override shouldAutorotateToInterfaceOrientation in the subclass to only allow landscape, which it sounds like you already have done. In your parent view controller and the tabBarController you will want to make sure that they are forwarding the autorotate methods to your subclass. You can check this by putting an NSLog in your subclasses implementation of shouldAutorotateToInterfaceOrientation.
Then, when you want to show the video, add a subclass of MPMoviePlayerViewController to it.
When you load your subclass of the movies player, try doing this in the parent view controller:
[self addChildViewController:self.subclassedMoviePlayerViewController];
[self.view addSubview:self.currentViewController.view];
[self.subclassedMoviePlayerViewController didMoveToParentViewController:self];
or if you want to animate the change you can do something like this:
CGRect viewFrame=self.subclassedMoviePlayerViewController.view.frame;
CGFloat viewHeight=inputViewFrame.size.height;
CGRect newFrame=CGRectMake(0, self.view.frame.size.height, viewFrame.size.width, viewFrame.size.height);
self.subclassedMoviePlayerViewController.view.frame=newFrame;
[self addChildViewController:self.subclassedMoviePlayerViewController];
CGRect offSetRect=CGRectOffset(newFrame, 0, -inputViewHeight);
[self.view addSubview:self.subclassedMoviePlayerViewController.view];
[UIView animateWithDuration:0.2
animations:^{
self.subclassedMoviePlayerViewController.view.frame=offSetRect;
}
completion:^(BOOL finished){
[self.subclassedMoviePlayerViewController didMoveToParentViewController:self];
}];
Of course you will have to set the frame for the view for the subclass of the movies player view controller before you add it.
then when you want to remove it:
[self.subclassedMoviePlayerViewController willMoveToParentViewController:nil];
[self.subclassedMoviePlayerViewController.view removeFromSuperView];
[self.subclassedMoviePlayerViewController removeFromParentViewController];
Good luck
t
Finally solved this!
Ok so there is an important method that must be overwritten in the parent view controller (in my case, the tab view's controller):
-(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
return NO;//This must be NO to allow any child views to use their own orientation
}
And then in the MPMoviePlayerViewController I subclassed, set this for the orientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;//This allows all orientations, set it to whatever you want
}
Then I present the MPMoviePlayerViewController like this from the tab view controller:
- (IBAction)buttonVideo:(id)sender {
MovieViewController *vc = [[MovieViewController alloc] initWithContentURL:#"http://www.MY-VIDEO-URL.com"];
[self presentMoviePlayerViewControllerAnimated:vc];
}
And WA-LA! A movie player that allows all orientations within a portrait locked, tab bar application!

UITabBar autorotate issue

I'm wondering why iPad project based on UITabBarController won't autorotate when i specify some of the tab should autorotate in landscape mode and the other will autorotate in landscape and portrait mode.
i've used the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
for all the UIViewController and specify if landscape return YES; other wise return NO;
In the other hand, if the UIViewController should rotate in landscape and portrait i've justreturn YES;` always.
Thx in advance.
for all the UIViewController you are loading in tabbarcontroller you must return True in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
Note:
A tab bar controller will not auto rotate unless ALL the controllers it contains also auto rotate.
from Rotate one UIViewController in UITabBar application -->>
There is no easy way to have only one view in landscape mode, while the others are in landscape, nor an easy way to programmatically switch to landscape mode.
One possible approach would be using a CGAffineTransform to transform your view in your viewWillAppear (i.e., right before the view is shown):
- (void)viewWillAppear:(BOOL)animated; {
//-- Adjust the status bar
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
//-- Rotate the view
CGAffineTransform toLandscape = CGAffineTransformMakeRotation(degreesToRadian(90));
toLandscape = CGAffineTransformTranslate(toLandscape, +90.0, +90.0 );
[self.view setTransform:toLandscape];
}

Resources