UIViewController interfaceOrientation problem - uiviewcontroller

I have a Subclass of UIViewController as usual. When I load the App, I need to size some elements that I have to put in programmatically. Of course, the size depends on the interface orientation: So, I did:
- (void)viewDidLoad {
switch( [self interfaceOrientation] ) {
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
NSLog(#"Portrait");
break:
case UIInterfaceOrientationLandscapeLeft:
case UIInterfaceOrientationLandscapeRight:
NSLog(#"Landscape");
break;
}
But no matter of the orientation of the simulator/device, the case is always Portrait in viewDidLoad/WillAppear, even if everything rotate correctly.
In the Plist I've added all supported orientations.
Hints?

Try [UIApplication sharedApplication].statusBarOrientation and check for UIDeviceOrientationPortrait, UIDeviceOrientationPortraitUpsideDown etc in your switch as [self interfaceOrientation] is unreliable in my experience.

1) Make sure that interface orientation in willAppear returns incorrect interface orientation.
2) try to look here http://developer.apple.com/library/ios/#qa/qa1688/_index.html
3) Make sure that main view controller is only viewcontroller in window (there is only one vc in window)

I was working with the rotations and orientations of the iOS App. I found that self.interfaceOrientation will always give you a correct result if called in viewDidAppear or after that.
[UIApplication sharedApplication].statusBarOrientation should be preferred when adding a view directly to UIWindow.
Hope it helps.

Related

How to lock orientation of one view controller to landscape mode [iOS13]

I have this solution: How to lock orientation of one view controller to portrait mode only in Swift
It was working fine but now on iOS 13 it didn't work anymore.
I try this solution: Screen rotation glitch on iPadOS 13
But it doesn't fix it.
Can someone have a working solution for iPhone app in portrait but only one UIViewController in landscape?
Edit:
I made a sample app, it is working fine with iOS 12.4.2 and iPhone 6.
But my problem it isn't working with iOS 13.1.3 and iPhone X.
=> we.tl/t-I3Um0U43fV
Edit 2:
Thanks to #donnywals, I success to keep my orientation as on iOS 12.
I just need some help to clean the main screen during transition. The "TOP" label is 90px from top of superview. As you can see, the current portrait page is resized during the transition.
Anyone know how to avoid it?
You can lock a view controller's orientation by overriding its supportedInterfaceOrientations property:
class ViewController: UIViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
// rest of your code
}
Edit:
Based on the sample project, you need to opt-out of the new presentation style to get the same behavior you had on iOS 13. Either set modalPresentationStyle = .fullScreen on the view controller that you're presenting in code or select the corresponding option in Interface Builder.
This is a tested code and I have implemented the same and its working for me - Forcing a controller to landscape mode
In the method viewWillAppear add the following:
NSNumber *value=[NSNumber numberWithInt: UIDeviceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
Add the following methods to the view controller
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation{
return (UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight);}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}
- (BOOL)shouldAutorotate {
return true;}

Embedding UIViewController with intrinsicContentsize

I try to implement a view that has on the top a view with dynamic height and below a UICollectionView in a storyboard.
As long as I layout that directly in one ViewController everything works fine.
When the top view is managed by a separate ViewController and embedded, I always run into autolayout problems:
SizingSample[53440:11697282] [LayoutConstraints] Unable to simultaneously satisfy constraints. (
"<NSLayoutConstraint:0x6000030cc690 UILayoutGuide:0x600002af9180'UIViewSafeAreaLayoutGuide'.bottom == SizingSample.DynamicSizeView:0x7fda024197b0.bottom + 3 (active)>",
"<NSLayoutConstraint:0x6000030cc960 SizingSample.DynamicSizeView:0x7fda024197b0.top == UILayoutGuide:0x600002af9180'UIViewSafeAreaLayoutGuide'.top + 20 (active)>",
"<NSLayoutConstraint:0x6000030c52c0 'UIView-Encapsulated-Layout-Height' UIView:0x7fda024195d0.height == 0 (active)>",
"<NSLayoutConstraint:0x6000030cc870 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x600002af9180'UIViewSafeAreaLayoutGuide']-(0)-| (active, names: '|':UIView:0x7fda024195d0 )>",
"<NSLayoutConstraint:0x6000030cc7d0 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x600002af9180'UIViewSafeAreaLayoutGuide'] (active, names: '|':UIView:0x7fda024195d0 )>"
)
IMO the 'UIView-Encapsulated-Layout-Height' constraint breaks everything, but I haven't found any way to prevent it.
A striped down sample can be found at https://github.com/tengelmeier/viewcontroller-embedding-problem.git
How can I autolayout a view honoring the dynamic size of an embedded view(..controller)?
Because ios Automatically Apply Fixed Frame set while embedding ContainerController.you have to tell don’t translate autoresizing mask into LayoutConstraint.
You can do this by setting following Property in ContainerViewController(destination Controller) ViewdidLoad method.
view.translatesAutoresizingMaskIntoConstraints = false

iOS9: UIViewController: viewWillTransitionToSize is not called on split view changes when viewController is running in a second UIWindow

My application uses two UIWindows, a first running the main application and a second running some stuff to be shown in foreground of all. Both windows have a view controller. When the split view size of my application changes, viewWillTransitionToSize is called on the main applications UIViewController, but not on the viewController of the second window. When the orientation of the application changes, both methods are called. What can I do, that both viewWillTransitionToSize selectors are called?
As an workaround I'm observing the main application window size ...
[[UIApplication sharedApplication].delegate.window
addObserver:self
forKeyPath:#"frame"
options:0
context:0];
... and update the layout of the second window content:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (object == [UIApplication sharedApplication].delegate.window) {
[self updateLayout];
}
}

Coding a custom navigationItem.rightBarButtonItem once and having it reused in both UITableViewControllers and UIViewControllers?

I have successfully added a rightBarButtonItem to my navigationBar, but I would prefer to only have the code to do so show up once rather than once per type of ViewController. Here's my current setup:
-->TVC
|
NVC--->TVC--->TVC--->VC
So far I've subclassed UITableViewController and moved my code for adding the button into my subclass. All 3 of my TableViewControllers are set to that subclass and it works perfectly.
However now I need my lone ViewController to also show the button, but I don't know how to accomplish this without duplicating the code from my TVC subclass. Is subclassing the right answer or do I need a different approach?
Edits:
#CarlVeazey - Sure, I call it from the viewDidLoad function.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"BETA" style:UIBarButtonItemStylePlain target:self action:#selector(betaPressed)];
Do a pull-up refactor into a UIViewController category. If your project already has one, just add this code there, otherwise press cmd-N in Xcode to create a new file and choose "Objective-C Category" and enter UIViewController in the "Category On" field.
In the interface add this method declaration:
- (void)onfConfigureRightNavigationBarButton;
And in the implementation add this method implementation:
- (void)onfConfigureRightNavigationBarButton
{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"BETA"
style:UIBarButtonItemStylePlain
target:self
action:#selector(betaPressed)];
}
Then in any UIViewController subclass you can import your category header and call this method. You may also wish to add to your category an empty implementation of betaPressed:.
BTW, ONF is the prefix I use for non-work coding so use whatever prefix already is in your project, or none at all if you're not concerned with category name collisions.

Adding custom UIView to UIViewController in - (void)loadView (Objective-C)

I am taking a programming class (for noobs) and I need to create the UIViewController graphViewController's view programmatically (without interface builder).
The view is simple, it only consists of an IBOUtlet which is an instance of a UIView subclass called GraphView. graphView responds to several multitouch gestures for zooming and panning and what-not, but I handle all of that stuff in - (void)viewDidLoad.
I am doing just the creation of the self.view property and graphView in the code below:
- (void)loadView
{
UIView *gvcView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = gvcView;
[gvcView release];
GraphView *aGraph = [[GraphView alloc] initWithFrame:self.view.bounds];
self.graphView = aGraph;
[aGraph release];
}
When I run the app I do not see the graphView view in there. I just get a transparent view which shows the "My Universal App" label. I'm stumped. Please help.
Let me know if you need additional code.
Thanks!
Update: Big thanks to BJ Homer for the quick fix!
had to do the following:
add this line of code: [self.view addSubview:self.graphView]; at the end.
I was also getting this strange bug where graphView was showing up as completely black. This line of code fixed that: self.graphView.backgroundColor = [UIColor whiteColor];
And that's it!
Final question: Is the default background color black for a custom UIView?
Thanks again!
[self.view addSubview:self.graphView];
Until you add your graph view to a parent view, UIKit doesn't know where to display it. self.view is special, since that's the property that -loadView is supposed to set. That view will automatically be added to the screen. But your graph view is just floating off in the ether until you add it somewhere.