I added a webview to a UIViewController. I assumed that I could match it's size to the UIViewController's view, but soon realised that the UIControllerView frame was independent of the screen orientation, and so displayed the frame as it would be in portrait mode (so the wrong way around, if the screen was in landscape). Doing UIInterfaceOrientationIsPortrait() doesn't work, because if the device is lying flat then it still reports it as being in portrait, even if the screen is rotated to landscape.
To get around this problem, i checked the orientation of the status bar and then used the UIScreen bounds (also independent of rotation) to work out the current frame, and then removed the size of the status bar, if it's visible.
CGRect frame = [UIScreen mainScreen].bounds;
BOOL isPortrait;
UIDeviceOrientation orientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
isPortrait = YES;
}
else {
isPortrait = NO;
}
if (!isPortrait) {
frame = CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.width);
}
if ([UIApplication sharedApplication].statusBarHidden) {
return frame;
}
else {
return CGRectMake(frame.origin.x,
frame.origin.y,
frame.size.width,
frame.size.height - 20);
}
Now I've run into another problem - even though I set up my UIWebView for autoresizing, the UIViewController's view's frame is independent of rotation, so it doesn't change, therefore my UIWebView doesn't change frame correctly upon rotation.
(Oddly, despite the UIViewController view frame not changing, the view does actually resize itself correctly)
I've tried using the method didRotateFromInterfaceOrientation:, which did resize it, but only after all the rotation animation was done.
Using willRotateToInterfaceOrientation:duration: poses the same problem as earlier - that UIInterfaceOrientationIsPortrait() isn't a true reflection of the orientation.
Anybody managed to do this?
try autoresizing both webview and viewcontroller's view. or you can also take another view and delete default view in nib file of viewcontroller. Autoresize that view and connect to view outlet.
Related
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.
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.
Background:
My app was configured in portrait view by default, but for one scene the screen should be in landscape view only.
Question:
How to set the orientation manually with codes, in other words, users need not to rotate the device to generate an event to make the screen rotated.
PS:
I need a method like "setRequestedOrientation" in Android or I need to know how to construct a screen rotation event to send to the system.
Have you on the desired view controller tried
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Another thing you can do is to change the orientation on the desired view controller from "Inferred" to "Landscape" in the Attributes inspector in your storyboard.
UIViewController Class Reference
Key:
Use CGAffineTransform CGAffineTransformMakeRotation(CGFloat angle) from CoreGraphics, which could make your view rotated
Sample Codes:
(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.transform = CGAffineTransformMakeRotation(M_PI/2);
self.view.frame = CGRectMake(0, 0, 480, 320);
}
I've been adding support for rotation for an app recently and it has been a pain. One thing I'm finding that's fairly consistently annoying is that one of my views shifts up by about 50 pixels or so everytime I rotate between my landscape and portrait mode.
My landscape mode is not actually the same view controller; I push a viewcontroller when I rotate. However, when I rotate back, I have to reset the portrait's view.bounds or else my view ends up shifting upwards.
So in my rotation code, I have to do this:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if ( self.tabBarController.view.subviews.count >= 2 )
{
if(toOrientation == UIInterfaceOrientationPortrait)
{
self.tabBarController.tabBar.hidden = NO;
self.navigationController.navigationBar.hidden = NO;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
self.view.bounds = CGRectMake(0, -55, width, height);
}
}
}
Surely this can't be right. In my app, there is a navbar and the standard status bar (batt life, reception, etc) occupying the top of my app. But...it seems like my view is slipping too upwards unless I set the y coordinate origin to be negative (which makes no sense!).
What's happening?
In my app, I hide the tabbar and navbar when I go to landscape mode. The statements to make the bars hidden are written into the portrait view's viewcontroller's code.
When I transition back from landscape mode to portrait mode, the landscape viewcontroller gets popped and I get the weird shifted views. Turns out this was caused by the order in which the tab/nav bar un-hiding statements.
My tab/nav bar un-hiding statements were in the portrait viewcontroller, so they were called too late. After moving the tab/nav un-hiding statements to the rotation code in the landscape viewcontroller (rather than the portrait's viewcontroller), my problem disappeared.
What I tried so far is, in viewDidLoad, I called
self.bannerView.autoresizingMask=UIViewAutoresizingFlexibleWidth;
and
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
if (newInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || newInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.bannerView.frame=CGRectMake(0.0,
0.0,
480.0,
GAD_SIZE_320x50.height);
}
// Position the UI elements for portrait mode
else {
self.bannerView.frame=CGRectMake(0.0,
0.0,
GAD_SIZE_320x50.width,
GAD_SIZE_320x50.height);
}
}
Both of these didn't work for me.
Hmm, I don't think that AdMob's creatives can stretch to fit the size of the screen when in landscape. So despite the fact that you're stretching the frame of the view to fit, the ad itself I think will stay the same size.
This means you should still see an ad come in on orientation changes, it will just look like it's the same size (make sure to make another request for an ad in the willAnimateRotationToInterfaceOrientation: method to see this).
You don't need to do any moves, but you must set correct rootViewController for adMovView.
If you use view controller model please add line in each custom view controller
adMobView.rootViewController = viewController;
where viewController - root view controller of your app.
Do not code like this
adMobView.rootViewController = self;
in custom view!