Create fullscreen UIView on rotatable UIViewController - objective-c

I have a UIViewController which supports all interface Orientations. The views are created programatically in the loadView() which works so far. All the views added in the loadView() method have the correct size and rotation.
However any views added later on are not rotated correctly. If I add the following UIView
[[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
it is only fullscreen if the UIViewController was in portrait mode when the UIView was added. If the device was in landscape mode the UIView is only 748 pixels wide, not the 1024 I would expect. [[UIScreen mainScreen] applicationFrame].size.width delivers 768 pixels or 748 pixels depending on the device's rotation.
So how should I create and add the UIView so it is shown with the full screen size? I would also like to init the UIView's content only for one mode (portrait OR landscape) and have it autoresized for the other mode. I basically need to tell the UIView it is a portrait mode view and should be rotated when added to a landscape view controller.

Since I couldn't init the UIView with the correct size, I just left the initialization code like it was (always creating the view in portrait mode) and resized the UIView later to the parent view's bounds property. Unlike the frame property, bounds seems to return the correct size depending on the current rotation.

Related

OSX Fullscreen (Kiosk) Application with Custom Resolution

I have an OS X Metal application that I would like to run in fullscreen at a non-native resolution, e.g. my native resolution is 1920x1080 and I would like to render the app in fullscreen at 1024x768. (I don't believe that using Metal to draw things impacts this question other than I am unable to use the OpenGL-specific NSView functions.)
My renderer uses a back buffer with a hard-coded size of 1024x768.
When I create my window with bounds = 1024x768 I get a fullscreen window, but my content is drawn centered and it does not stretch to fill the whole screen.
When I create my window with bounds = 1920x1080 I get a fullscreen window, but my content is drawn in the upper-left corner and incorrectly scaled (because of the ratio mismatch between the two resolutions).
Using [NSView - enterFullScreenMode:withOptions:] yielded the same results. Setting [NSView autoresizingMask] didn't change anything either.
Ideally I want the window to be the size of the screen and have the low-resolution back buffer be stretched to fill the whole window. What am I missing that would allow me to do that?
The relevant app initialization from my NSResponder <NSApplicationDelegate>:
// Create the window
self.Window = [NSWindow alloc];
[self.Window initWithContentRect:bounds
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
// Create the view
self.View = [NSView alloc];
[self.View initWithFrame:bounds];
[self.View setWantsLayer:YES]; // The generated layer is CAMetalLayer
// Associate the view with the window
[self.Window setContentView:self.View];
// Misc
[self.Window makeKeyAndOrderFront:self.Window];
[self.Window setAcceptsMouseMovedEvents:YES];
[self.Window setHidesOnDeactivate:YES];
// Fullscreen
[self.Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[self.Window toggleFullScreen:nil];
[self.Window makeFirstResponder:self.View];
Thanks.
The layer that backs a view is constrained to have its frame equal to that view's bounds. By default, the drawableSize of a CAMetalLayer is equal to its bounds times its contents scale. However, you can set it to any size you desire by explicitly setting the layer's drawableSize.

Unable to add UIScrollView to UITableView

UPDATED -- I have an iPad app that was originally designed and written for portrait mode only; I now want to add a UIScrollView so it will scroll in landscape mode. Auto Layout is checked and the different scenes are built using Storyboard. (I am following this tutorial). The major problem is when switching from portrait to landscape, the bounds of the frame change drastically, thereby causing problems with the logic of the scroll.
This is the image of the first scene (UIView) I am trying to add a UIScrollView to:
This is what it looks like in landscape mode (w/o scrolling):
This is my code in the -viewDidLoad method for that scene:
// create UIScrollView
UIScrollView *scroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0,0,self.bookDetailView.frame.size.width, self.bookDetailView.frame.size.height)];
scroll.delegate = self;
scroll.pagingEnabled = YES;
scroll.scrollEnabled = YES;
scroll.showsVerticalScrollIndicator = YES;
CGSize scrollableSize = CGSizeMake(768, 1024); // size of portrait mode
scroll.contentSize = scrollableSize;
[self.view addSubview: scroll];
The scroll bar (as thin as it is) now shows, BUT although it moves like it should, the UIView doesn't move. Portrait mode works fine (no scrolling needed) but landscape mode doesn't scroll at all (even tho' the vertical scroll bar does move). I'm wondrering if I should abandon the idea of using scrolling for landscape mode and create separate scenes for landscape mode instead.
Is there any reason why you need a separate UIScrollView ? UITableView is already a scroll view. My guess is that the touch events from the UIScrollView you created are interfering with those of the UITableView.

self.view.frame.size.height returns 568 on iphone 4s instead of 480

In the viewDidLoad method my view controller I call self.view.frame.size.height which returns 568. But [[UIScreen mainScreen] bounds].size.height return 480. Shouldn't the frame size of a view always be less than the window size?
I'm testing on a iphone 4s. I tried setting the length of a sub view to [[UIScreen mainScreen] bounds].size.height and it was not enough to cover the screen. I then checked the size of self.view.frame.size.height and that is how I came across the 568 which doesn't make any sense to me yet.
viewDidLayoutSubviews will return the correct height.
I.e, call self.view.frame.size.height in the view hierarchy-method viewDidLayoutSubviews
In viewDidLoad the views don't have their final size. Typically they have the size taken from their XIB/Storyboard.
For example, if you design xibs for i5, the controller view will be 568 px high in viewDidLoad. However, before it appears on the screen a new layout is calculated (depending on your autolayout constraints or autoresizing mask).
A fix for your problem - never use the screen height. If you want to cover the entire controller, use its height self.view.frame.size.height instead.
Also don't forget to add constraints or set the autoresizing mask.

How to resize UIPageViewController in landscape

I am having an issue with resizing UIPageViewController in landscape mode.
Here is my scenario:
I have a UIViewController which has a scrollview in it.
I added a UIPageViewController to the scrollview programmatically and it is displaying all my view controllers in each page correctly.
When i change the device orientation to landscape i am correctly changing the content size of the scrollview but the PageViewController is displaying only up to half of its contents. Can you please help me with this one.
Thanks,
Anand.
It looks like you are either not getting the correct orientation of your device or trying to set it in the viewDidLoad function. The following code should correctly set your page view controller's frame to current orientation.
- (void)viewWillLayoutSubviews {
CGRect screenFrame = [[UIScreen mainScreen] applicationFrame];
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
screenFrame = CGRectMake(0, 0, screenFrame.size.height, screenFrame.size.width);
}
//Please don't forget to replace _myPageViewController with your variable
_myPageViewController.frame = screenFrame;
}
Please note that code is getting called from viewWillLayoutSubviews
function.

UIScrollView.size = view.size - allAdditionalBars.size (like TabBar or NavigationBar) programmatically

UIScrollView is set programmatically, please dont post answers with using .xib file.
My UIScrollView is situated in my model class, so i want the code to be able to be easly imported to another project eg. for iPad or with rotating screen.
I have a view:
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width;, self.view.frame.size.height;)];
And my UIScrollView. I want to set it's size to cover all screen not counting all bars that my controller class will have. But i dont know how ;)
I though about subtracting self.view.frame.size.height - self.navigationController.navigationBar.frame.height and self.tabBarController.tabBar.height if each exists.
Is there any method that automatically sets UIScrollView size..?
Thank you in advance!
In your UIViewController subclass, you don't need to worry about the size of any UINavigationController or UITabBarController chrome. Those controllers will automatically resize your controller's main view to fit the appropriate content area.
If I'm creating the UIView myself in the controller's loadView, I usually just initially size it at [[UIScreen mainScreen] applicationFrame]. If I were to add a UIScrollView as a subview that would fill up the entire area of the main view (rather than just using the UIScrollView directly as the main view), I would use self.view.bounds as its frame and be sure to set autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;.